Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/Analysis/src/Error.cpp
2725 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
#include "Luau/Error.h"
3
4
#include "Luau/Clone.h"
5
#include "Luau/Common.h"
6
#include "Luau/FileResolver.h"
7
#include "Luau/NotNull.h"
8
#include "Luau/StringUtils.h"
9
#include "Luau/ToString.h"
10
#include "Luau/Type.h"
11
#include "Luau/TypeChecker2.h"
12
#include "Luau/TypeFunction.h"
13
14
#include <optional>
15
#include <string>
16
#include <type_traits>
17
#include <unordered_set>
18
19
LUAU_FASTINTVARIABLE(LuauIndentTypeMismatchMaxTypeLength, 10)
20
21
LUAU_FASTFLAG(LuauTypeCheckerUdtfRenameClassToExtern)
22
23
static std::string wrongNumberOfArgsString(
24
size_t expectedCount,
25
std::optional<size_t> maximumCount,
26
size_t actualCount,
27
const char* argPrefix = nullptr,
28
bool isVariadic = false
29
)
30
{
31
std::string s = "expects ";
32
33
if (isVariadic)
34
s += "at least ";
35
36
s += std::to_string(expectedCount) + " ";
37
38
if (maximumCount && expectedCount != *maximumCount)
39
s += "to " + std::to_string(*maximumCount) + " ";
40
41
if (argPrefix)
42
s += std::string(argPrefix) + " ";
43
44
s += "argument";
45
if ((maximumCount ? *maximumCount : expectedCount) != 1)
46
s += "s";
47
48
s += ", but ";
49
50
if (actualCount == 0)
51
{
52
s += "none";
53
}
54
else
55
{
56
if (actualCount < expectedCount)
57
s += "only ";
58
59
s += std::to_string(actualCount);
60
}
61
62
s += (actualCount == 1) ? " is" : " are";
63
64
s += " specified";
65
66
return s;
67
}
68
69
namespace Luau
70
{
71
72
// this list of binary operator type functions is used for better stringification of type functions errors
73
static const std::unordered_map<std::string, const char*> kBinaryOps{
74
{"add", "+"},
75
{"sub", "-"},
76
{"mul", "*"},
77
{"div", "/"},
78
{"idiv", "//"},
79
{"pow", "^"},
80
{"mod", "%"},
81
{"concat", ".."},
82
{"lt", "< or >="},
83
{"le", "<= or >"},
84
{"eq", "== or ~="}
85
};
86
87
// this list of unary operator type functions is used for better stringification of type functions errors
88
static const std::unordered_map<std::string, const char*> kUnaryOps{{"unm", "-"}, {"len", "#"}, {"not", "not"}};
89
90
// this list of type functions will receive a special error indicating that the user should file a bug on the GitHub repository
91
// putting a type function in this list indicates that it is expected to _always_ reduce
92
static const std::unordered_set<std::string> kUnreachableTypeFunctions{"refine", "singleton", "union", "intersect", "and", "or"};
93
94
struct ErrorConverter
95
{
96
FileResolver* fileResolver = nullptr;
97
98
std::string operator()(const Luau::TypeMismatch& tm) const
99
{
100
std::string givenTypeName = Luau::toString(tm.givenType);
101
std::string wantedTypeName = Luau::toString(tm.wantedType);
102
103
std::string result;
104
105
auto quote = [&](std::string s)
106
{
107
return "'" + s + "'";
108
};
109
110
auto constructErrorMessage = [&](std::string givenType,
111
std::string wantedType,
112
std::optional<std::string> givenModule,
113
std::optional<std::string> wantedModule) -> std::string
114
{
115
std::string given = givenModule ? quote(givenType) + " from " + quote(*givenModule) : quote(givenType);
116
std::string wanted = wantedModule ? quote(wantedType) + " from " + quote(*wantedModule) : quote(wantedType);
117
size_t luauIndentTypeMismatchMaxTypeLength = size_t(FInt::LuauIndentTypeMismatchMaxTypeLength);
118
if (get<NeverType>(follow(tm.wantedType)))
119
{
120
if (givenType.length() <= luauIndentTypeMismatchMaxTypeLength)
121
return "Expected this to be unreachable, but got " + given;
122
return "Expected this to be unreachable, but got\n\t" + given;
123
}
124
125
if (tm.context == TypeMismatch::InvariantContext)
126
{
127
if (givenType.length() <= luauIndentTypeMismatchMaxTypeLength || wantedType.length() <= luauIndentTypeMismatchMaxTypeLength)
128
return "Expected this to be exactly " + wanted + ", but got " + given;
129
return "Expected this to be exactly\n\t" + wanted + "\nbut got\n\t" + given;
130
}
131
132
if (givenType.length() <= luauIndentTypeMismatchMaxTypeLength || wantedType.length() <= luauIndentTypeMismatchMaxTypeLength)
133
return "Expected this to be " + wanted + ", but got " + given;
134
return "Expected this to be\n\t" + wanted + "\nbut got\n\t" + given;
135
};
136
137
if (givenTypeName == wantedTypeName)
138
{
139
if (auto givenDefinitionModule = getDefinitionModuleName(tm.givenType))
140
{
141
if (auto wantedDefinitionModule = getDefinitionModuleName(tm.wantedType))
142
{
143
if (fileResolver != nullptr)
144
{
145
std::string givenModuleName = fileResolver->getHumanReadableModuleName(*givenDefinitionModule);
146
std::string wantedModuleName = fileResolver->getHumanReadableModuleName(*wantedDefinitionModule);
147
result = constructErrorMessage(givenTypeName, wantedTypeName, givenModuleName, wantedModuleName);
148
}
149
else
150
{
151
result = constructErrorMessage(givenTypeName, wantedTypeName, *givenDefinitionModule, *wantedDefinitionModule);
152
}
153
}
154
}
155
}
156
157
if (result.empty())
158
result = constructErrorMessage(std::move(givenTypeName), std::move(wantedTypeName), std::nullopt, std::nullopt);
159
160
161
if (tm.error)
162
{
163
result += "\ncaused by:\n ";
164
165
if (!tm.reason.empty())
166
result += tm.reason + "\n";
167
168
result += Luau::toString(*tm.error, TypeErrorToStringOptions{fileResolver});
169
}
170
else if (!tm.reason.empty())
171
{
172
result += "; " + tm.reason;
173
}
174
175
return result;
176
}
177
178
std::string operator()(const Luau::UnknownSymbol& e) const
179
{
180
switch (e.context)
181
{
182
case UnknownSymbol::Binding:
183
return "Unknown global '" + e.name + "'; consider assigning to it first";
184
case UnknownSymbol::Type:
185
return "Unknown type '" + e.name + "'";
186
}
187
188
LUAU_ASSERT(!"Unexpected context for UnknownSymbol");
189
return "";
190
}
191
192
std::string operator()(const Luau::UnknownProperty& e) const
193
{
194
TypeId t = follow(e.table);
195
if (get<TableType>(t))
196
return "Key '" + e.key + "' not found in table '" + Luau::toString(t) + "'";
197
else if (get<ExternType>(t))
198
{
199
if (FFlag::LuauTypeCheckerUdtfRenameClassToExtern)
200
return "Key '" + e.key + "' not found in external type '" + Luau::toString(t) + "'";
201
else
202
return "Key '" + e.key + "' not found in class '" + Luau::toString(t) + "'";
203
}
204
else
205
return "Type '" + Luau::toString(e.table) + "' does not have key '" + e.key + "'";
206
}
207
208
std::string operator()(const Luau::NotATable& e) const
209
{
210
return "Expected type table, got '" + Luau::toString(e.ty) + "' instead";
211
}
212
213
std::string operator()(const Luau::CannotExtendTable& e) const
214
{
215
switch (e.context)
216
{
217
case Luau::CannotExtendTable::Property:
218
return "Cannot add property '" + e.prop + "' to table '" + Luau::toString(e.tableType) + "'";
219
case Luau::CannotExtendTable::Metatable:
220
return "Cannot add metatable to table '" + Luau::toString(e.tableType) + "'";
221
case Luau::CannotExtendTable::Indexer:
222
return "Cannot add indexer to table '" + Luau::toString(e.tableType) + "'";
223
}
224
225
LUAU_ASSERT(!"Unknown context");
226
return "";
227
}
228
229
std::string operator()(const Luau::CannotCompareUnrelatedTypes& e) const
230
{
231
return "Cannot compare unrelated types '" + toString(e.left) + "' and '" + toString(e.right) + "' with '" + toString(e.op) + "'";
232
}
233
234
std::string operator()(const Luau::OnlyTablesCanHaveMethods& e) const
235
{
236
return "Cannot add method to non-table type '" + Luau::toString(e.tableType) + "'";
237
}
238
239
std::string operator()(const Luau::DuplicateTypeDefinition& e) const
240
{
241
std::string s = "Redefinition of type '" + e.name + "'";
242
if (e.previousLocation)
243
s += ", previously defined at line " + std::to_string(e.previousLocation->begin.line + 1);
244
return s;
245
}
246
247
std::string operator()(const Luau::CountMismatch& e) const
248
{
249
const std::string expectedS = e.expected == 1 ? "" : "s";
250
const std::string actualVerb = e.actual == 1 ? "is" : "are";
251
252
switch (e.context)
253
{
254
case CountMismatch::Return:
255
return "Expected to return " + std::to_string(e.expected) + " value" + expectedS + ", but " + std::to_string(e.actual) + " " +
256
actualVerb + " returned here";
257
case CountMismatch::FunctionResult:
258
// It is alright if right hand side produces more values than the
259
// left hand side accepts. In this context consider only the opposite case.
260
return "Function only returns " + std::to_string(e.expected) + " value" + expectedS + ", but " + std::to_string(e.actual) + " " +
261
actualVerb + " required here";
262
case CountMismatch::ExprListResult:
263
return "Expression list has " + std::to_string(e.expected) + " value" + expectedS + ", but " + std::to_string(e.actual) + " " +
264
actualVerb + " required here";
265
case CountMismatch::Arg:
266
if (!e.function.empty())
267
return "Argument count mismatch. Function '" + e.function + "' " +
268
wrongNumberOfArgsString(e.expected, e.maximum, e.actual, /*argPrefix*/ nullptr, e.isVariadic);
269
else
270
return "Argument count mismatch. Function " +
271
wrongNumberOfArgsString(e.expected, e.maximum, e.actual, /*argPrefix*/ nullptr, e.isVariadic);
272
}
273
274
LUAU_ASSERT(!"Unknown context");
275
return "";
276
}
277
278
std::string operator()(const Luau::FunctionDoesNotTakeSelf&) const
279
{
280
return std::string("This function does not take self. Did you mean to use a dot instead of a colon?");
281
}
282
283
std::string operator()(const Luau::FunctionRequiresSelf& e) const
284
{
285
return "This function must be called with self. Did you mean to use a colon instead of a dot?";
286
}
287
288
std::string operator()(const Luau::OccursCheckFailed&) const
289
{
290
return "Type contains a self-recursive construct that cannot be resolved";
291
}
292
293
std::string operator()(const Luau::UnknownRequire& e) const
294
{
295
if (e.modulePath.empty())
296
return "Unknown require: unsupported path";
297
else
298
return "Unknown require: " + e.modulePath;
299
}
300
301
std::string operator()(const Luau::IncorrectGenericParameterCount& e) const
302
{
303
std::string name = e.name;
304
if (!e.typeFun.typeParams.empty() || !e.typeFun.typePackParams.empty())
305
{
306
name += "<";
307
bool first = true;
308
for (auto param : e.typeFun.typeParams)
309
{
310
if (first)
311
first = false;
312
else
313
name += ", ";
314
315
name += toString(param.ty);
316
}
317
318
for (auto param : e.typeFun.typePackParams)
319
{
320
if (first)
321
first = false;
322
else
323
name += ", ";
324
325
name += toString(param.tp);
326
}
327
328
name += ">";
329
}
330
331
if (e.typeFun.typeParams.size() != e.actualParameters)
332
return "Generic type '" + name + "' " +
333
wrongNumberOfArgsString(e.typeFun.typeParams.size(), std::nullopt, e.actualParameters, "type", !e.typeFun.typePackParams.empty());
334
335
return "Generic type '" + name + "' " +
336
wrongNumberOfArgsString(e.typeFun.typePackParams.size(), std::nullopt, e.actualPackParameters, "type pack", /*isVariadic*/ false);
337
}
338
339
std::string operator()(const Luau::SyntaxError& e) const
340
{
341
return e.message;
342
}
343
344
std::string operator()(const Luau::CodeTooComplex&) const
345
{
346
return "Code is too complex to typecheck! Consider simplifying the code around this area";
347
}
348
349
std::string operator()(const Luau::UnificationTooComplex&) const
350
{
351
return "Internal error: Code is too complex to typecheck! Consider adding type annotations around this area";
352
}
353
354
std::string operator()(const Luau::UnknownPropButFoundLikeProp& e) const
355
{
356
std::string candidatesSuggestion = "Did you mean ";
357
if (e.candidates.size() != 1)
358
candidatesSuggestion += "one of ";
359
360
bool first = true;
361
for (Name name : e.candidates)
362
{
363
if (first)
364
first = false;
365
else
366
candidatesSuggestion += ", ";
367
368
candidatesSuggestion += "'" + name + "'";
369
}
370
371
std::string s = "Key '" + e.key + "' not found in ";
372
373
TypeId t = follow(e.table);
374
if (get<ExternType>(t))
375
{
376
if (FFlag::LuauTypeCheckerUdtfRenameClassToExtern)
377
s += "external type";
378
else
379
s += "class";
380
}
381
else
382
s += "table";
383
384
s += " '" + toString(e.table) + "'. " + candidatesSuggestion + "?";
385
return s;
386
}
387
388
std::string operator()(const Luau::GenericError& e) const
389
{
390
return e.message;
391
}
392
393
std::string operator()(const Luau::InternalError& e) const
394
{
395
return e.message;
396
}
397
398
std::string operator()(const Luau::ConstraintSolvingIncompleteError& e) const
399
{
400
return "Type inference failed to complete, you may see some confusing types and type errors.";
401
}
402
403
std::optional<TypeId> findCallMetamethod(TypeId type) const
404
{
405
type = follow(type);
406
407
std::optional<TypeId> metatable;
408
if (const MetatableType* mtType = get<MetatableType>(type))
409
metatable = mtType->metatable;
410
else if (const ExternType* externType = get<ExternType>(type))
411
metatable = externType->metatable;
412
413
if (!metatable)
414
return std::nullopt;
415
416
TypeId unwrapped = follow(*metatable);
417
418
if (get<AnyType>(unwrapped))
419
return unwrapped;
420
421
const TableType* mtt = getTableType(unwrapped);
422
if (!mtt)
423
return std::nullopt;
424
425
auto it = mtt->props.find("__call");
426
if (it != mtt->props.end())
427
{
428
return it->second.readTy;
429
}
430
else
431
return std::nullopt;
432
}
433
434
std::string operator()(const Luau::CannotCallNonFunction& e) const
435
{
436
if (auto unionTy = get<UnionType>(follow(e.ty)))
437
{
438
std::string err = "Cannot call a value of the union type:";
439
440
for (auto option : unionTy)
441
{
442
option = follow(option);
443
444
if (get<FunctionType>(option) || findCallMetamethod(option))
445
{
446
err += "\n | " + toString(option);
447
continue;
448
}
449
450
// early-exit if we find something that isn't callable in the union.
451
return "Cannot call a value of type " + toString(option) + " in union:\n " + toString(e.ty);
452
}
453
454
err += "\nWe are unable to determine the appropriate result type for such a call.";
455
456
return err;
457
}
458
459
if (auto primitiveTy = get<PrimitiveType>(follow(e.ty)); primitiveTy && primitiveTy->type == PrimitiveType::Function)
460
return "The type " + toString(e.ty) + " is not precise enough for us to determine the appropriate result type of this call.";
461
462
return "Cannot call a value of type " + toString(e.ty);
463
}
464
std::string operator()(const Luau::ExtraInformation& e) const
465
{
466
return e.message;
467
}
468
469
std::string operator()(const Luau::DeprecatedApiUsed& e) const
470
{
471
return "The property ." + e.symbol + " is deprecated. Use ." + e.useInstead + " instead.";
472
}
473
474
std::string operator()(const Luau::ModuleHasCyclicDependency& e) const
475
{
476
if (e.cycle.empty())
477
return "Cyclic module dependency detected";
478
479
std::string s = "Cyclic module dependency: ";
480
481
bool first = true;
482
for (const ModuleName& name : e.cycle)
483
{
484
if (first)
485
first = false;
486
else
487
s += " -> ";
488
489
if (fileResolver != nullptr)
490
s += fileResolver->getHumanReadableModuleName(name);
491
else
492
s += name;
493
}
494
495
return s;
496
}
497
498
std::string operator()(const Luau::FunctionExitsWithoutReturning& e) const
499
{
500
return "Not all codepaths in this function return '" + toString(e.expectedReturnType) + "'.";
501
}
502
503
std::string operator()(const Luau::IllegalRequire& e) const
504
{
505
return "Cannot require module " + e.moduleName + ": " + e.reason;
506
}
507
508
std::string operator()(const Luau::MissingProperties& e) const
509
{
510
std::string s = "Table type '" + toString(e.subType) + "' not compatible with type '" + toString(e.superType) + "' because the former";
511
512
switch (e.context)
513
{
514
case MissingProperties::Missing:
515
s += " is missing field";
516
break;
517
case MissingProperties::Extra:
518
s += " has extra field";
519
break;
520
}
521
522
if (e.properties.size() > 1)
523
s += "s";
524
525
s += " ";
526
527
for (size_t i = 0; i < e.properties.size(); ++i)
528
{
529
if (i > 0)
530
s += ", ";
531
532
if (i > 0 && i == e.properties.size() - 1)
533
s += "and ";
534
535
s += "'" + e.properties[i] + "'";
536
}
537
538
return s;
539
}
540
541
std::string operator()(const Luau::DuplicateGenericParameter& e) const
542
{
543
return "Duplicate type parameter '" + e.parameterName + "'";
544
}
545
546
std::string operator()(const Luau::CannotInferBinaryOperation& e) const
547
{
548
std::string ss = "Unknown type used in " + toString(e.op);
549
550
switch (e.kind)
551
{
552
case Luau::CannotInferBinaryOperation::Comparison:
553
ss += " comparison";
554
break;
555
case Luau::CannotInferBinaryOperation::Operation:
556
ss += " operation";
557
}
558
559
if (e.suggestedToAnnotate)
560
ss += "; consider adding a type annotation to '" + *e.suggestedToAnnotate + "'";
561
562
return ss;
563
}
564
565
std::string operator()(const Luau::SwappedGenericTypeParameter& e) const
566
{
567
switch (e.kind)
568
{
569
case Luau::SwappedGenericTypeParameter::Type:
570
return "Variadic type parameter '" + e.name + "...' is used as a regular generic type; consider changing '" + e.name + "...' to '" +
571
e.name + "' in the generic argument list";
572
case Luau::SwappedGenericTypeParameter::Pack:
573
return "Generic type '" + e.name + "' is used as a variadic type parameter; consider changing '" + e.name + "' to '" + e.name +
574
"...' in the generic argument list";
575
default:
576
LUAU_ASSERT(!"Unknown kind");
577
return "";
578
}
579
}
580
581
std::string operator()(const Luau::OptionalValueAccess& e) const
582
{
583
return "Value of type '" + toString(e.optional) + "' could be nil";
584
}
585
586
std::string operator()(const Luau::MissingUnionProperty& e) const
587
{
588
std::string ss = "Key '" + e.key + "' is missing from ";
589
590
bool first = true;
591
for (auto ty : e.missing)
592
{
593
if (first)
594
first = false;
595
else
596
ss += ", ";
597
598
ss += "'" + toString(ty) + "'";
599
}
600
601
return ss + " in the type '" + toString(e.type) + "'";
602
}
603
604
std::string operator()(const TypesAreUnrelated& e) const
605
{
606
return "Cannot cast '" + toString(e.left) + "' into '" + toString(e.right) + "' because the types are unrelated";
607
}
608
609
std::string operator()(const NormalizationTooComplex&) const
610
{
611
return "Code is too complex to typecheck! Consider simplifying the code around this area";
612
}
613
614
std::string operator()(const TypePackMismatch& e) const
615
{
616
std::string ss = "Expected this to be '" + toString(e.wantedTp) + "', but got '" + toString(e.givenTp) + "'";
617
618
if (!e.reason.empty())
619
ss += "; " + e.reason;
620
621
return ss;
622
}
623
624
std::string operator()(const DynamicPropertyLookupOnExternTypesUnsafe& e) const
625
{
626
return "Attempting a dynamic property access on type '" + Luau::toString(e.ty) + "' is unsafe and may cause exceptions at runtime";
627
}
628
629
std::string operator()(const UninhabitedTypeFunction& e) const
630
{
631
auto tfit = get<TypeFunctionInstanceType>(e.ty);
632
LUAU_ASSERT(tfit); // Luau analysis has actually done something wrong if this type is not a type function.
633
if (!tfit)
634
return "Internal error: Unexpected type " + Luau::toString(e.ty) + " flagged as an uninhabited type function.";
635
636
// unary operators
637
if (auto unaryString = kUnaryOps.find(tfit->function->name); unaryString != kUnaryOps.end())
638
{
639
std::string result = "Operator '" + std::string(unaryString->second) + "' could not be applied to ";
640
641
if (tfit->typeArguments.size() == 1 && tfit->packArguments.empty())
642
{
643
result += "operand of type " + Luau::toString(tfit->typeArguments[0]);
644
645
if (tfit->function->name != "not")
646
result += "; there is no corresponding overload for __" + tfit->function->name;
647
}
648
else
649
{
650
// if it's not the expected case, we ought to add a specialization later, but this is a sane default.
651
result += "operands of types ";
652
653
bool isFirst = true;
654
for (auto arg : tfit->typeArguments)
655
{
656
if (!isFirst)
657
result += ", ";
658
659
result += Luau::toString(arg);
660
isFirst = false;
661
}
662
663
for (auto packArg : tfit->packArguments)
664
result += ", " + Luau::toString(packArg);
665
}
666
667
return result;
668
}
669
670
// binary operators
671
if (auto binaryString = kBinaryOps.find(tfit->function->name); binaryString != kBinaryOps.end())
672
{
673
std::string result = "Operator '" + std::string(binaryString->second) + "' could not be applied to operands of types ";
674
675
if (tfit->typeArguments.size() == 2 && tfit->packArguments.empty())
676
{
677
// this is the expected case.
678
result += Luau::toString(tfit->typeArguments[0]) + " and " + Luau::toString(tfit->typeArguments[1]);
679
}
680
else
681
{
682
// if it's not the expected case, we ought to add a specialization later, but this is a sane default.
683
684
bool isFirst = true;
685
for (auto arg : tfit->typeArguments)
686
{
687
if (!isFirst)
688
result += ", ";
689
690
result += Luau::toString(arg);
691
isFirst = false;
692
}
693
694
for (auto packArg : tfit->packArguments)
695
result += ", " + Luau::toString(packArg);
696
}
697
698
result += "; there is no corresponding overload for __" + tfit->function->name;
699
700
return result;
701
}
702
703
// miscellaneous
704
705
if ("keyof" == tfit->function->name || "rawkeyof" == tfit->function->name)
706
{
707
if (tfit->typeArguments.size() == 1 && tfit->packArguments.empty())
708
return "Type '" + toString(tfit->typeArguments[0]) + "' does not have keys, so '" + Luau::toString(e.ty) + "' is invalid";
709
else
710
return "Type function instance " + Luau::toString(e.ty) + " is ill-formed, and thus invalid";
711
}
712
713
if ("index" == tfit->function->name || "rawget" == tfit->function->name)
714
{
715
if (tfit->typeArguments.size() != 2)
716
return "Type function instance " + Luau::toString(e.ty) + " is ill-formed, and thus invalid";
717
718
if (get<ErrorType>(tfit->typeArguments[1])) // Second argument to (index | rawget)<_,_> is not a type
719
return "Second argument to " + tfit->function->name + "<" + Luau::toString(tfit->typeArguments[0]) + ", _> is not a valid index type";
720
else // Property `indexer` does not exist on type `indexee`
721
return "Property '" + Luau::toString(tfit->typeArguments[1]) + "' does not exist on type '" + Luau::toString(tfit->typeArguments[0]) +
722
"'";
723
}
724
725
if (kUnreachableTypeFunctions.count(tfit->function->name))
726
{
727
return "Type function instance " + Luau::toString(e.ty) + " is uninhabited\n" +
728
"This is likely to be a bug, please report it at https://github.com/luau-lang/luau/issues";
729
}
730
731
// Everything should be specialized above to report a more descriptive error that hopefully does not mention "type functions" explicitly.
732
// If we produce this message, it's an indication that we've missed a specialization and it should be fixed!
733
return "Type function instance " + Luau::toString(e.ty) + " is uninhabited";
734
}
735
736
std::string operator()(const ExplicitFunctionAnnotationRecommended& r) const
737
{
738
std::string toReturn = toString(r.recommendedReturn);
739
std::string argAnnotations;
740
for (auto [arg, type] : r.recommendedArgs)
741
{
742
argAnnotations += arg + ": " + toString(type) + ", ";
743
}
744
if (argAnnotations.length() >= 2)
745
{
746
argAnnotations.pop_back();
747
argAnnotations.pop_back();
748
}
749
750
if (argAnnotations.empty())
751
return "Consider annotating the return with " + toReturn;
752
753
return "Consider placing the following annotations on the arguments: " + argAnnotations + " or instead annotating the return as " + toReturn;
754
}
755
756
std::string operator()(const UninhabitedTypePackFunction& e) const
757
{
758
return "Type pack function instance " + Luau::toString(e.tp) + " is uninhabited";
759
}
760
761
std::string operator()(const WhereClauseNeeded& e) const
762
{
763
return "Type function instance " + Luau::toString(e.ty) +
764
" depends on generic function parameters but does not appear in the function signature; this construct cannot be type-checked at this "
765
"time";
766
}
767
768
std::string operator()(const PackWhereClauseNeeded& e) const
769
{
770
return "Type pack function instance " + Luau::toString(e.tp) +
771
" depends on generic function parameters but does not appear in the function signature; this construct cannot be type-checked at this "
772
"time";
773
}
774
775
std::string operator()(const CheckedFunctionCallError& e) const
776
{
777
return "the function '" + e.checkedFunctionName + "' expects to get a " + toString(e.expected) + " as its " +
778
toHumanReadableIndex(e.argumentIndex) + " argument, but is being given a " + toString(e.passed) + "";
779
}
780
781
std::string operator()(const NonStrictFunctionDefinitionError& e) const
782
{
783
std::string prefix = e.functionName.empty() ? "" : "in the function '" + e.functionName + "', '";
784
return prefix + "the argument '" + e.argument + "' is used in a way that will error at runtime";
785
}
786
787
std::string operator()(const PropertyAccessViolation& e) const
788
{
789
const std::string stringKey = isIdentifier(e.key) ? e.key : "\"" + e.key + "\"";
790
switch (e.context)
791
{
792
case PropertyAccessViolation::CannotRead:
793
return "Property " + stringKey + " of table '" + toString(e.table) + "' is write-only";
794
case PropertyAccessViolation::CannotWrite:
795
return "Property " + stringKey + " of table '" + toString(e.table) + "' is read-only";
796
}
797
798
LUAU_UNREACHABLE();
799
return "<Invalid PropertyAccessViolation>";
800
}
801
802
std::string operator()(const CheckedFunctionIncorrectArgs& e) const
803
{
804
805
return "the function '" + e.functionName + "' will error at runtime if it is not called with " + std::to_string(e.expected) +
806
" arguments, but we are calling it here with " + std::to_string(e.actual) + " arguments";
807
}
808
809
std::string operator()(const UnexpectedTypeInSubtyping& e) const
810
{
811
return "Encountered an unexpected type in subtyping: " + toString(e.ty);
812
}
813
814
std::string operator()(const UnexpectedTypePackInSubtyping& e) const
815
{
816
return "Encountered an unexpected type pack in subtyping: " + toString(e.tp);
817
}
818
819
std::string operator()(const UserDefinedTypeFunctionError& e) const
820
{
821
return e.message;
822
}
823
824
std::string operator()(const BuiltInTypeFunctionError& e) const
825
{
826
return toString(e.error);
827
}
828
829
std::string operator()(const ReservedIdentifier& e) const
830
{
831
return e.name + " cannot be used as an identifier for a type function or alias";
832
}
833
834
std::string operator()(const CannotAssignToNever& e) const
835
{
836
std::string result = "Cannot assign a value of type " + toString(e.rhsType) + " to a field of type never";
837
838
switch (e.reason)
839
{
840
case CannotAssignToNever::Reason::PropertyNarrowed:
841
if (!e.cause.empty())
842
{
843
result += "\ncaused by the property being given the following incompatible types:\n";
844
for (auto ty : e.cause)
845
result += " " + toString(ty) + "\n";
846
result += "There are no values that could safely satisfy all of these types at once.";
847
}
848
}
849
850
return result;
851
}
852
853
std::string operator()(const UnexpectedArrayLikeTableItem&) const
854
{
855
return "Unexpected array-like table item: the indexer key type of this table is not `number`.";
856
}
857
858
std::string operator()(const CannotCheckDynamicStringFormatCalls& e) const
859
{
860
return "We cannot statically check the type of `string.format` when called with a format string that is not statically known.\n"
861
"If you'd like to use an unchecked `string.format` call, you can cast the format string to `any` using `:: any`.";
862
}
863
864
865
std::string operator()(const GenericTypeCountMismatch& e) const
866
{
867
return "Different number of generic type parameters: subtype had " + std::to_string(e.subTyGenericCount) + ", supertype had " +
868
std::to_string(e.superTyGenericCount) + ".";
869
}
870
871
std::string operator()(const GenericTypePackCountMismatch& e) const
872
{
873
return "Different number of generic type pack parameters: subtype had " + std::to_string(e.subTyGenericPackCount) + ", supertype had " +
874
std::to_string(e.superTyGenericPackCount) + ".";
875
}
876
877
std::string operator()(const MultipleNonviableOverloads& e) const
878
{
879
return "None of the overloads for function that accept " + std::to_string(e.attemptedArgCount) + " arguments are compatible.";
880
}
881
882
std::string operator()(const RecursiveRestraintViolation& e) const
883
{
884
return "Recursive type being used with different parameters.";
885
}
886
887
std::string operator()(const GenericBoundsMismatch& e) const
888
{
889
std::string lowerBounds;
890
for (size_t i = 0; i < e.lowerBounds.size(); ++i)
891
{
892
if (i > 0)
893
lowerBounds += " | ";
894
lowerBounds += Luau::toString(e.lowerBounds[i]);
895
}
896
std::string upperBounds;
897
for (size_t i = 0; i < e.upperBounds.size(); ++i)
898
{
899
if (i > 0)
900
upperBounds += " & ";
901
upperBounds += Luau::toString(e.upperBounds[i]);
902
}
903
904
return "No valid instantiation could be inferred for generic type parameter " + std::string{e.genericName} +
905
". It was expected to be at least:\n\t" + lowerBounds + "\nand at most:\n\t" + upperBounds +
906
"\nbut these types are not compatible with one another.";
907
}
908
909
std::string operator()(const InstantiateGenericsOnNonFunction& e) const
910
{
911
switch (e.interestingEdgeCase)
912
{
913
case InstantiateGenericsOnNonFunction::InterestingEdgeCase::None:
914
return "Cannot instantiate type parameters on something without type parameters.";
915
case InstantiateGenericsOnNonFunction::InterestingEdgeCase::MetatableCall:
916
// `__call` is complicated because `f<<T>>()` is interpreted as `f<<T>>` as its own expression that is then called.
917
// This is so that you can write code like `local f2 = f<<number>>`, and then call `f2()`.
918
// With metatables, it's not so obvious what this would result in.
919
return "Luau does not currently support explicitly instantiating a table with a `__call` metamethod. \
920
You may be able to work around this by creating a function that calls the table, and using that instead.";
921
case InstantiateGenericsOnNonFunction::InterestingEdgeCase::Intersection:
922
return "Luau does not currently support explicitly instantiating an overloaded function type.";
923
default:
924
LUAU_ASSERT(false);
925
return ""; // MSVC exhaustive
926
}
927
}
928
929
std::string operator()(const TypeInstantiationCountMismatch& e) const
930
{
931
LUAU_ASSERT(e.providedTypes > e.maximumTypes || e.providedTypePacks > e.maximumTypePacks);
932
933
std::string result = "Too many type parameters passed to ";
934
935
if (e.functionName)
936
{
937
result += "'";
938
result += *e.functionName;
939
result += "', which is typed as ";
940
}
941
else
942
{
943
result += "function typed as ";
944
}
945
946
result += toString(e.functionType);
947
result += ". Expected ";
948
949
if (e.providedTypes > e.maximumTypes)
950
{
951
result += "at most ";
952
result += std::to_string(e.maximumTypes);
953
result += " type parameter";
954
if (e.maximumTypes != 1)
955
{
956
result += "s";
957
}
958
result += ", but ";
959
result += std::to_string(e.providedTypes);
960
result += " provided";
961
962
if (e.providedTypePacks > e.maximumTypePacks)
963
{
964
result += ". Also expected ";
965
}
966
}
967
968
if (e.providedTypePacks > e.maximumTypePacks)
969
{
970
result += "at most ";
971
result += std::to_string(e.maximumTypePacks);
972
result += " type pack";
973
if (e.maximumTypePacks != 1)
974
{
975
result += "s";
976
}
977
result += ", but ";
978
result += std::to_string(e.providedTypePacks);
979
result += " provided";
980
}
981
982
result += ".";
983
984
return result;
985
}
986
987
std::string operator()(const UnappliedTypeFunction&) const
988
{
989
return "Type functions always require `<>` when referenced.";
990
}
991
992
std::string operator()(const AmbiguousFunctionCall& afc) const
993
{
994
return "Calling function " + toString(afc.function) + " with argument pack " + toString(afc.arguments) + " is ambiguous.";
995
}
996
};
997
998
struct InvalidNameChecker
999
{
1000
std::string invalidName = "%error-id%";
1001
1002
bool operator()(const Luau::UnknownProperty& e) const
1003
{
1004
return e.key == invalidName;
1005
}
1006
bool operator()(const Luau::CannotExtendTable& e) const
1007
{
1008
return e.prop == invalidName;
1009
}
1010
bool operator()(const Luau::DuplicateTypeDefinition& e) const
1011
{
1012
return e.name == invalidName;
1013
}
1014
1015
template<typename T>
1016
bool operator()(const T& other) const
1017
{
1018
return false;
1019
}
1020
};
1021
1022
TypeMismatch::TypeMismatch(TypeId wantedType, TypeId givenType)
1023
: wantedType(wantedType)
1024
, givenType(givenType)
1025
{
1026
}
1027
1028
TypeMismatch::TypeMismatch(TypeId wantedType, TypeId givenType, std::string reason)
1029
: wantedType(wantedType)
1030
, givenType(givenType)
1031
, reason(std::move(reason))
1032
{
1033
}
1034
1035
TypeMismatch::TypeMismatch(TypeId wantedType, TypeId givenType, std::string reason, std::optional<TypeError> error)
1036
: wantedType(wantedType)
1037
, givenType(givenType)
1038
, reason(std::move(reason))
1039
, error(error ? std::make_shared<TypeError>(std::move(*error)) : nullptr)
1040
{
1041
}
1042
1043
TypeMismatch::TypeMismatch(TypeId wantedType, TypeId givenType, TypeMismatch::Context context)
1044
: wantedType(wantedType)
1045
, givenType(givenType)
1046
, context(context)
1047
{
1048
}
1049
1050
TypeMismatch::TypeMismatch(TypeId wantedType, TypeId givenType, std::string reason, TypeMismatch::Context context)
1051
: wantedType(wantedType)
1052
, givenType(givenType)
1053
, context(context)
1054
, reason(std::move(reason))
1055
{
1056
}
1057
1058
TypeMismatch::TypeMismatch(TypeId wantedType, TypeId givenType, std::string reason, std::optional<TypeError> error, TypeMismatch::Context context)
1059
: wantedType(wantedType)
1060
, givenType(givenType)
1061
, context(context)
1062
, reason(std::move(reason))
1063
, error(error ? std::make_shared<TypeError>(std::move(*error)) : nullptr)
1064
{
1065
}
1066
1067
bool TypeMismatch::operator==(const TypeMismatch& rhs) const
1068
{
1069
if (!!error != !!rhs.error)
1070
return false;
1071
1072
if (error && !(*error == *rhs.error))
1073
return false;
1074
1075
return *wantedType == *rhs.wantedType && *givenType == *rhs.givenType && reason == rhs.reason && context == rhs.context;
1076
}
1077
1078
bool UnknownSymbol::operator==(const UnknownSymbol& rhs) const
1079
{
1080
return name == rhs.name;
1081
}
1082
1083
bool UnknownProperty::operator==(const UnknownProperty& rhs) const
1084
{
1085
return *table == *rhs.table && key == rhs.key;
1086
}
1087
1088
bool PropertyAccessViolation::operator==(const PropertyAccessViolation& rhs) const
1089
{
1090
return *table == *rhs.table && key == rhs.key && context == rhs.context;
1091
}
1092
1093
bool NotATable::operator==(const NotATable& rhs) const
1094
{
1095
return ty == rhs.ty;
1096
}
1097
1098
bool CannotExtendTable::operator==(const CannotExtendTable& rhs) const
1099
{
1100
return *tableType == *rhs.tableType && prop == rhs.prop && context == rhs.context;
1101
}
1102
1103
bool CannotCompareUnrelatedTypes::operator==(const CannotCompareUnrelatedTypes& rhs) const
1104
{
1105
return *left == *rhs.left && right == rhs.right && op == rhs.op;
1106
}
1107
1108
bool OnlyTablesCanHaveMethods::operator==(const OnlyTablesCanHaveMethods& rhs) const
1109
{
1110
return *tableType == *rhs.tableType;
1111
}
1112
1113
bool DuplicateTypeDefinition::operator==(const DuplicateTypeDefinition& rhs) const
1114
{
1115
return name == rhs.name && previousLocation == rhs.previousLocation;
1116
}
1117
1118
bool CountMismatch::operator==(const CountMismatch& rhs) const
1119
{
1120
return expected == rhs.expected && maximum == rhs.maximum && actual == rhs.actual && context == rhs.context && function == rhs.function;
1121
}
1122
1123
bool FunctionDoesNotTakeSelf::operator==(const FunctionDoesNotTakeSelf&) const
1124
{
1125
return true;
1126
}
1127
1128
bool FunctionRequiresSelf::operator==(const FunctionRequiresSelf& e) const
1129
{
1130
return true;
1131
}
1132
1133
bool OccursCheckFailed::operator==(const OccursCheckFailed&) const
1134
{
1135
return true;
1136
}
1137
1138
bool UnknownRequire::operator==(const UnknownRequire& rhs) const
1139
{
1140
return modulePath == rhs.modulePath;
1141
}
1142
1143
bool IncorrectGenericParameterCount::operator==(const IncorrectGenericParameterCount& rhs) const
1144
{
1145
if (name != rhs.name)
1146
return false;
1147
1148
if (typeFun.type != rhs.typeFun.type)
1149
return false;
1150
1151
if (typeFun.typeParams.size() != rhs.typeFun.typeParams.size())
1152
return false;
1153
1154
if (typeFun.typePackParams.size() != rhs.typeFun.typePackParams.size())
1155
return false;
1156
1157
for (size_t i = 0; i < typeFun.typeParams.size(); ++i)
1158
{
1159
if (typeFun.typeParams[i].ty != rhs.typeFun.typeParams[i].ty)
1160
return false;
1161
}
1162
1163
for (size_t i = 0; i < typeFun.typePackParams.size(); ++i)
1164
{
1165
if (typeFun.typePackParams[i].tp != rhs.typeFun.typePackParams[i].tp)
1166
return false;
1167
}
1168
1169
return true;
1170
}
1171
1172
bool SyntaxError::operator==(const SyntaxError& rhs) const
1173
{
1174
return message == rhs.message;
1175
}
1176
1177
bool CodeTooComplex::operator==(const CodeTooComplex&) const
1178
{
1179
return true;
1180
}
1181
1182
bool UnificationTooComplex::operator==(const UnificationTooComplex&) const
1183
{
1184
return true;
1185
}
1186
1187
bool UnknownPropButFoundLikeProp::operator==(const UnknownPropButFoundLikeProp& rhs) const
1188
{
1189
return *table == *rhs.table && key == rhs.key && candidates.size() == rhs.candidates.size() &&
1190
std::equal(candidates.begin(), candidates.end(), rhs.candidates.begin());
1191
}
1192
1193
bool GenericError::operator==(const GenericError& rhs) const
1194
{
1195
return message == rhs.message;
1196
}
1197
1198
bool InternalError::operator==(const InternalError& rhs) const
1199
{
1200
return message == rhs.message;
1201
}
1202
1203
bool ConstraintSolvingIncompleteError::operator==(const ConstraintSolvingIncompleteError& rhs) const
1204
{
1205
return true;
1206
}
1207
1208
bool CannotCallNonFunction::operator==(const CannotCallNonFunction& rhs) const
1209
{
1210
return ty == rhs.ty;
1211
}
1212
1213
bool ExtraInformation::operator==(const ExtraInformation& rhs) const
1214
{
1215
return message == rhs.message;
1216
}
1217
1218
bool DeprecatedApiUsed::operator==(const DeprecatedApiUsed& rhs) const
1219
{
1220
return symbol == rhs.symbol && useInstead == rhs.useInstead;
1221
}
1222
1223
bool FunctionExitsWithoutReturning::operator==(const FunctionExitsWithoutReturning& rhs) const
1224
{
1225
return expectedReturnType == rhs.expectedReturnType;
1226
}
1227
1228
int TypeError::code() const
1229
{
1230
return minCode() + int(data.index());
1231
}
1232
1233
int TypeError::minCode()
1234
{
1235
return 1000;
1236
}
1237
1238
TypeErrorSummary TypeError::summary() const
1239
{
1240
return TypeErrorSummary{location, moduleName, code()};
1241
}
1242
1243
bool TypeError::operator==(const TypeError& rhs) const
1244
{
1245
return location == rhs.location && data == rhs.data;
1246
}
1247
1248
bool ModuleHasCyclicDependency::operator==(const ModuleHasCyclicDependency& rhs) const
1249
{
1250
return cycle.size() == rhs.cycle.size() && std::equal(cycle.begin(), cycle.end(), rhs.cycle.begin());
1251
}
1252
1253
bool IllegalRequire::operator==(const IllegalRequire& rhs) const
1254
{
1255
return moduleName == rhs.moduleName && reason == rhs.reason;
1256
}
1257
1258
bool MissingProperties::operator==(const MissingProperties& rhs) const
1259
{
1260
return *superType == *rhs.superType && *subType == *rhs.subType && properties.size() == rhs.properties.size() &&
1261
std::equal(properties.begin(), properties.end(), rhs.properties.begin()) && context == rhs.context;
1262
}
1263
1264
bool DuplicateGenericParameter::operator==(const DuplicateGenericParameter& rhs) const
1265
{
1266
return parameterName == rhs.parameterName;
1267
}
1268
1269
bool CannotInferBinaryOperation::operator==(const CannotInferBinaryOperation& rhs) const
1270
{
1271
return op == rhs.op && suggestedToAnnotate == rhs.suggestedToAnnotate && kind == rhs.kind;
1272
}
1273
1274
bool SwappedGenericTypeParameter::operator==(const SwappedGenericTypeParameter& rhs) const
1275
{
1276
return name == rhs.name && kind == rhs.kind;
1277
}
1278
1279
bool OptionalValueAccess::operator==(const OptionalValueAccess& rhs) const
1280
{
1281
return *optional == *rhs.optional;
1282
}
1283
1284
bool MissingUnionProperty::operator==(const MissingUnionProperty& rhs) const
1285
{
1286
if (missing.size() != rhs.missing.size())
1287
return false;
1288
1289
for (size_t i = 0; i < missing.size(); ++i)
1290
{
1291
if (*missing[i] != *rhs.missing[i])
1292
return false;
1293
}
1294
1295
return *type == *rhs.type && key == rhs.key;
1296
}
1297
1298
bool TypesAreUnrelated::operator==(const TypesAreUnrelated& rhs) const
1299
{
1300
return left == rhs.left && right == rhs.right;
1301
}
1302
1303
bool TypePackMismatch::operator==(const TypePackMismatch& rhs) const
1304
{
1305
return *wantedTp == *rhs.wantedTp && *givenTp == *rhs.givenTp;
1306
}
1307
1308
bool DynamicPropertyLookupOnExternTypesUnsafe::operator==(const DynamicPropertyLookupOnExternTypesUnsafe& rhs) const
1309
{
1310
return ty == rhs.ty;
1311
}
1312
1313
bool UninhabitedTypeFunction::operator==(const UninhabitedTypeFunction& rhs) const
1314
{
1315
return ty == rhs.ty;
1316
}
1317
1318
1319
bool ExplicitFunctionAnnotationRecommended::operator==(const ExplicitFunctionAnnotationRecommended& rhs) const
1320
{
1321
return recommendedReturn == rhs.recommendedReturn && recommendedArgs == rhs.recommendedArgs;
1322
}
1323
1324
bool UninhabitedTypePackFunction::operator==(const UninhabitedTypePackFunction& rhs) const
1325
{
1326
return tp == rhs.tp;
1327
}
1328
1329
bool WhereClauseNeeded::operator==(const WhereClauseNeeded& rhs) const
1330
{
1331
return ty == rhs.ty;
1332
}
1333
1334
bool PackWhereClauseNeeded::operator==(const PackWhereClauseNeeded& rhs) const
1335
{
1336
return tp == rhs.tp;
1337
}
1338
1339
bool CheckedFunctionCallError::operator==(const CheckedFunctionCallError& rhs) const
1340
{
1341
return *expected == *rhs.expected && *passed == *rhs.passed && checkedFunctionName == rhs.checkedFunctionName &&
1342
argumentIndex == rhs.argumentIndex;
1343
}
1344
1345
bool NonStrictFunctionDefinitionError::operator==(const NonStrictFunctionDefinitionError& rhs) const
1346
{
1347
return functionName == rhs.functionName && argument == rhs.argument && argumentType == rhs.argumentType;
1348
}
1349
1350
bool CheckedFunctionIncorrectArgs::operator==(const CheckedFunctionIncorrectArgs& rhs) const
1351
{
1352
return functionName == rhs.functionName && expected == rhs.expected && actual == rhs.actual;
1353
}
1354
1355
bool UnexpectedTypeInSubtyping::operator==(const UnexpectedTypeInSubtyping& rhs) const
1356
{
1357
return ty == rhs.ty;
1358
}
1359
1360
bool UnexpectedTypePackInSubtyping::operator==(const UnexpectedTypePackInSubtyping& rhs) const
1361
{
1362
return tp == rhs.tp;
1363
}
1364
1365
bool UserDefinedTypeFunctionError::operator==(const UserDefinedTypeFunctionError& rhs) const
1366
{
1367
return message == rhs.message;
1368
}
1369
1370
bool BuiltInTypeFunctionError::operator==(const BuiltInTypeFunctionError& rhs) const
1371
{
1372
return error == rhs.error;
1373
}
1374
1375
bool ReservedIdentifier::operator==(const ReservedIdentifier& rhs) const
1376
{
1377
return name == rhs.name;
1378
}
1379
1380
bool CannotAssignToNever::operator==(const CannotAssignToNever& rhs) const
1381
{
1382
if (cause.size() != rhs.cause.size())
1383
return false;
1384
1385
for (size_t i = 0; i < cause.size(); ++i)
1386
{
1387
if (*cause[i] != *rhs.cause[i])
1388
return false;
1389
}
1390
1391
return *rhsType == *rhs.rhsType && reason == rhs.reason;
1392
}
1393
1394
bool GenericTypeCountMismatch::operator==(const GenericTypeCountMismatch& rhs) const
1395
{
1396
return subTyGenericCount == rhs.subTyGenericCount && superTyGenericCount == rhs.superTyGenericCount;
1397
}
1398
1399
bool GenericTypePackCountMismatch::operator==(const GenericTypePackCountMismatch& rhs) const
1400
{
1401
return subTyGenericPackCount == rhs.subTyGenericPackCount && superTyGenericPackCount == rhs.superTyGenericPackCount;
1402
}
1403
1404
bool MultipleNonviableOverloads::operator==(const MultipleNonviableOverloads& rhs) const
1405
{
1406
return attemptedArgCount == rhs.attemptedArgCount;
1407
}
1408
1409
bool InstantiateGenericsOnNonFunction::operator==(const InstantiateGenericsOnNonFunction& rhs) const
1410
{
1411
return interestingEdgeCase == rhs.interestingEdgeCase;
1412
}
1413
1414
bool TypeInstantiationCountMismatch::operator==(const TypeInstantiationCountMismatch& rhs) const
1415
{
1416
return functionName == rhs.functionName && functionType == rhs.functionType && providedTypes == rhs.providedTypes &&
1417
maximumTypes == rhs.maximumTypes && providedTypePacks == rhs.providedTypePacks && maximumTypePacks == rhs.maximumTypePacks;
1418
}
1419
1420
GenericBoundsMismatch::GenericBoundsMismatch(const std::string_view genericName, TypeIds lowerBoundSet, TypeIds upperBoundSet)
1421
: genericName(genericName)
1422
, lowerBounds(lowerBoundSet.take())
1423
, upperBounds(upperBoundSet.take())
1424
{
1425
}
1426
1427
bool GenericBoundsMismatch::operator==(const GenericBoundsMismatch& rhs) const
1428
{
1429
return genericName == rhs.genericName && lowerBounds == rhs.lowerBounds && upperBounds == rhs.upperBounds;
1430
}
1431
1432
bool UnappliedTypeFunction::operator==(const UnappliedTypeFunction& rhs) const
1433
{
1434
return true;
1435
}
1436
1437
bool AmbiguousFunctionCall::operator==(const AmbiguousFunctionCall& rhs) const
1438
{
1439
return function == rhs.function && arguments == rhs.arguments;
1440
}
1441
1442
1443
std::string toString(const TypeError& error)
1444
{
1445
return toString(error, TypeErrorToStringOptions{});
1446
}
1447
1448
std::string toString(const TypeError& error, TypeErrorToStringOptions options)
1449
{
1450
ErrorConverter converter{options.fileResolver};
1451
return Luau::visit(converter, error.data);
1452
}
1453
1454
bool containsParseErrorName(const TypeError& error)
1455
{
1456
return Luau::visit(InvalidNameChecker{}, error.data);
1457
}
1458
1459
template<typename T>
1460
void copyError(T& e, TypeArena& destArena, CloneState& cloneState)
1461
{
1462
auto clone = [&](auto&& ty)
1463
{
1464
return ::Luau::clone(ty, destArena, cloneState);
1465
};
1466
1467
auto visitErrorData = [&](auto&& e)
1468
{
1469
copyError(e, destArena, cloneState);
1470
};
1471
1472
if constexpr (false)
1473
{
1474
}
1475
else if constexpr (std::is_same_v<T, TypeMismatch>)
1476
{
1477
e.wantedType = clone(e.wantedType);
1478
e.givenType = clone(e.givenType);
1479
1480
if (e.error)
1481
visit(visitErrorData, e.error->data);
1482
}
1483
else if constexpr (std::is_same_v<T, UnknownSymbol>)
1484
{
1485
}
1486
else if constexpr (std::is_same_v<T, UnknownProperty>)
1487
{
1488
e.table = clone(e.table);
1489
}
1490
else if constexpr (std::is_same_v<T, NotATable>)
1491
{
1492
e.ty = clone(e.ty);
1493
}
1494
else if constexpr (std::is_same_v<T, CannotExtendTable>)
1495
{
1496
e.tableType = clone(e.tableType);
1497
}
1498
else if constexpr (std::is_same_v<T, CannotCompareUnrelatedTypes>)
1499
{
1500
e.left = clone(e.left);
1501
e.right = clone(e.right);
1502
}
1503
else if constexpr (std::is_same_v<T, OnlyTablesCanHaveMethods>)
1504
{
1505
e.tableType = clone(e.tableType);
1506
}
1507
else if constexpr (std::is_same_v<T, DuplicateTypeDefinition>)
1508
{
1509
}
1510
else if constexpr (std::is_same_v<T, CountMismatch>)
1511
{
1512
}
1513
else if constexpr (std::is_same_v<T, FunctionDoesNotTakeSelf>)
1514
{
1515
}
1516
else if constexpr (std::is_same_v<T, FunctionRequiresSelf>)
1517
{
1518
}
1519
else if constexpr (std::is_same_v<T, OccursCheckFailed>)
1520
{
1521
}
1522
else if constexpr (std::is_same_v<T, UnknownRequire>)
1523
{
1524
}
1525
else if constexpr (std::is_same_v<T, IncorrectGenericParameterCount>)
1526
{
1527
e.typeFun = clone(e.typeFun);
1528
}
1529
else if constexpr (std::is_same_v<T, SyntaxError>)
1530
{
1531
}
1532
else if constexpr (std::is_same_v<T, CodeTooComplex>)
1533
{
1534
}
1535
else if constexpr (std::is_same_v<T, UnificationTooComplex>)
1536
{
1537
}
1538
else if constexpr (std::is_same_v<T, UnknownPropButFoundLikeProp>)
1539
{
1540
e.table = clone(e.table);
1541
}
1542
else if constexpr (std::is_same_v<T, GenericError>)
1543
{
1544
}
1545
else if constexpr (std::is_same_v<T, InternalError>)
1546
{
1547
}
1548
else if constexpr (std::is_same_v<T, ConstraintSolvingIncompleteError>)
1549
{
1550
}
1551
else if constexpr (std::is_same_v<T, CannotCallNonFunction>)
1552
{
1553
e.ty = clone(e.ty);
1554
}
1555
else if constexpr (std::is_same_v<T, ExtraInformation>)
1556
{
1557
}
1558
else if constexpr (std::is_same_v<T, DeprecatedApiUsed>)
1559
{
1560
}
1561
else if constexpr (std::is_same_v<T, ModuleHasCyclicDependency>)
1562
{
1563
}
1564
else if constexpr (std::is_same_v<T, IllegalRequire>)
1565
{
1566
}
1567
else if constexpr (std::is_same_v<T, FunctionExitsWithoutReturning>)
1568
{
1569
e.expectedReturnType = clone(e.expectedReturnType);
1570
}
1571
else if constexpr (std::is_same_v<T, DuplicateGenericParameter>)
1572
{
1573
}
1574
else if constexpr (std::is_same_v<T, CannotInferBinaryOperation>)
1575
{
1576
}
1577
else if constexpr (std::is_same_v<T, MissingProperties>)
1578
{
1579
e.superType = clone(e.superType);
1580
e.subType = clone(e.subType);
1581
}
1582
else if constexpr (std::is_same_v<T, SwappedGenericTypeParameter>)
1583
{
1584
}
1585
else if constexpr (std::is_same_v<T, OptionalValueAccess>)
1586
{
1587
e.optional = clone(e.optional);
1588
}
1589
else if constexpr (std::is_same_v<T, MissingUnionProperty>)
1590
{
1591
e.type = clone(e.type);
1592
1593
for (auto& ty : e.missing)
1594
ty = clone(ty);
1595
}
1596
else if constexpr (std::is_same_v<T, TypesAreUnrelated>)
1597
{
1598
e.left = clone(e.left);
1599
e.right = clone(e.right);
1600
}
1601
else if constexpr (std::is_same_v<T, NormalizationTooComplex>)
1602
{
1603
}
1604
else if constexpr (std::is_same_v<T, TypePackMismatch>)
1605
{
1606
e.wantedTp = clone(e.wantedTp);
1607
e.givenTp = clone(e.givenTp);
1608
}
1609
else if constexpr (std::is_same_v<T, DynamicPropertyLookupOnExternTypesUnsafe>)
1610
e.ty = clone(e.ty);
1611
else if constexpr (std::is_same_v<T, UninhabitedTypeFunction>)
1612
e.ty = clone(e.ty);
1613
else if constexpr (std::is_same_v<T, ExplicitFunctionAnnotationRecommended>)
1614
{
1615
e.recommendedReturn = clone(e.recommendedReturn);
1616
for (auto& [_, t] : e.recommendedArgs)
1617
t = clone(t);
1618
}
1619
else if constexpr (std::is_same_v<T, UninhabitedTypePackFunction>)
1620
e.tp = clone(e.tp);
1621
else if constexpr (std::is_same_v<T, WhereClauseNeeded>)
1622
e.ty = clone(e.ty);
1623
else if constexpr (std::is_same_v<T, PackWhereClauseNeeded>)
1624
e.tp = clone(e.tp);
1625
else if constexpr (std::is_same_v<T, CheckedFunctionCallError>)
1626
{
1627
e.expected = clone(e.expected);
1628
e.passed = clone(e.passed);
1629
}
1630
else if constexpr (std::is_same_v<T, NonStrictFunctionDefinitionError>)
1631
{
1632
e.argumentType = clone(e.argumentType);
1633
}
1634
else if constexpr (std::is_same_v<T, PropertyAccessViolation>)
1635
e.table = clone(e.table);
1636
else if constexpr (std::is_same_v<T, CheckedFunctionIncorrectArgs>)
1637
{
1638
}
1639
else if constexpr (std::is_same_v<T, UnexpectedTypeInSubtyping>)
1640
e.ty = clone(e.ty);
1641
else if constexpr (std::is_same_v<T, UnexpectedTypePackInSubtyping>)
1642
e.tp = clone(e.tp);
1643
else if constexpr (std::is_same_v<T, UserDefinedTypeFunctionError>)
1644
{
1645
}
1646
else if constexpr (std::is_same_v<T, BuiltInTypeFunctionError>)
1647
{
1648
}
1649
else if constexpr (std::is_same_v<T, CannotAssignToNever>)
1650
{
1651
e.rhsType = clone(e.rhsType);
1652
1653
for (auto& ty : e.cause)
1654
ty = clone(ty);
1655
}
1656
else if constexpr (std::is_same_v<T, UnexpectedArrayLikeTableItem>)
1657
{
1658
}
1659
else if constexpr (std::is_same_v<T, ReservedIdentifier>)
1660
{
1661
}
1662
else if constexpr (std::is_same_v<T, CannotCheckDynamicStringFormatCalls>)
1663
{
1664
}
1665
else if constexpr (std::is_same_v<T, GenericTypeCountMismatch>)
1666
{
1667
}
1668
else if constexpr (std::is_same_v<T, GenericTypePackCountMismatch>)
1669
{
1670
}
1671
else if constexpr (std::is_same_v<T, MultipleNonviableOverloads>)
1672
{
1673
}
1674
else if constexpr (std::is_same_v<T, RecursiveRestraintViolation>)
1675
{
1676
}
1677
else if constexpr (std::is_same_v<T, GenericBoundsMismatch>)
1678
{
1679
for (auto& lowerBound : e.lowerBounds)
1680
lowerBound = clone(lowerBound);
1681
for (auto& upperBound : e.upperBounds)
1682
upperBound = clone(upperBound);
1683
}
1684
else if constexpr (std::is_same_v<T, InstantiateGenericsOnNonFunction>)
1685
{
1686
}
1687
else if constexpr (std::is_same_v<T, TypeInstantiationCountMismatch>)
1688
{
1689
e.functionType = clone(e.functionType);
1690
}
1691
else if constexpr (std::is_same_v<T, UnappliedTypeFunction>)
1692
{
1693
}
1694
else if constexpr (std::is_same_v<T, AmbiguousFunctionCall>)
1695
{
1696
e.function = clone(e.function);
1697
e.arguments = clone(e.arguments);
1698
}
1699
else
1700
static_assert(always_false_v<T>, "Non-exhaustive type switch");
1701
}
1702
1703
void copyErrors(ErrorVec& errors, TypeArena& destArena, NotNull<BuiltinTypes> builtinTypes)
1704
{
1705
CloneState cloneState{builtinTypes};
1706
1707
auto visitErrorData = [&](auto&& e)
1708
{
1709
copyError(e, destArena, cloneState);
1710
};
1711
1712
LUAU_ASSERT(!destArena.types.isFrozen());
1713
LUAU_ASSERT(!destArena.typePacks.isFrozen());
1714
1715
for (TypeError& error : errors)
1716
visit(visitErrorData, error.data);
1717
}
1718
1719
void InternalErrorReporter::ice(const std::string& message, const Location& location) const
1720
{
1721
InternalCompilerError error(message, moduleName, location);
1722
1723
if (onInternalError)
1724
onInternalError(error.what());
1725
1726
throw error;
1727
}
1728
1729
void InternalErrorReporter::ice(const std::string& message) const
1730
{
1731
InternalCompilerError error(message, moduleName);
1732
1733
if (onInternalError)
1734
onInternalError(error.what());
1735
1736
throw error;
1737
}
1738
1739
const char* InternalCompilerError::what() const throw()
1740
{
1741
return this->message.data();
1742
}
1743
1744
} // namespace Luau
1745
1746