Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/Analysis/include/Luau/Error.h
2727 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
#pragma once
3
4
#include "Luau/Ast.h"
5
#include "Luau/Location.h"
6
#include "Luau/NotNull.h"
7
#include "Luau/Type.h"
8
#include "Luau/TypeFunctionError.h"
9
#include "Luau/TypeIds.h"
10
#include "Luau/Variant.h"
11
12
#include <set>
13
14
namespace Luau
15
{
16
17
struct FileResolver;
18
struct TypeArena;
19
struct TypeError;
20
21
struct TypeMismatch
22
{
23
enum Context
24
{
25
CovariantContext,
26
InvariantContext
27
};
28
29
TypeMismatch() = default;
30
TypeMismatch(TypeId wantedType, TypeId givenType);
31
TypeMismatch(TypeId wantedType, TypeId givenType, std::string reason);
32
TypeMismatch(TypeId wantedType, TypeId givenType, std::string reason, std::optional<TypeError> error);
33
34
TypeMismatch(TypeId wantedType, TypeId givenType, Context context);
35
TypeMismatch(TypeId wantedType, TypeId givenType, std::string reason, Context context);
36
TypeMismatch(TypeId wantedType, TypeId givenType, std::string reason, std::optional<TypeError> error, Context context);
37
38
TypeId wantedType = nullptr;
39
TypeId givenType = nullptr;
40
Context context = CovariantContext;
41
42
std::string reason;
43
std::shared_ptr<TypeError> error;
44
45
bool operator==(const TypeMismatch& rhs) const;
46
};
47
48
struct UnknownSymbol
49
{
50
enum Context
51
{
52
Binding,
53
Type,
54
};
55
Name name;
56
Context context;
57
58
bool operator==(const UnknownSymbol& rhs) const;
59
};
60
61
struct UnknownProperty
62
{
63
TypeId table;
64
Name key;
65
66
bool operator==(const UnknownProperty& rhs) const;
67
};
68
69
struct NotATable
70
{
71
TypeId ty;
72
73
bool operator==(const NotATable& rhs) const;
74
};
75
76
struct CannotExtendTable
77
{
78
enum Context
79
{
80
Property,
81
Indexer,
82
Metatable
83
};
84
TypeId tableType;
85
Context context;
86
Name prop;
87
88
bool operator==(const CannotExtendTable& rhs) const;
89
};
90
91
struct CannotCompareUnrelatedTypes
92
{
93
TypeId left;
94
TypeId right;
95
AstExprBinary::Op op;
96
97
bool operator==(const CannotCompareUnrelatedTypes& rhs) const;
98
};
99
100
struct OnlyTablesCanHaveMethods
101
{
102
TypeId tableType;
103
104
bool operator==(const OnlyTablesCanHaveMethods& rhs) const;
105
};
106
107
struct DuplicateTypeDefinition
108
{
109
Name name;
110
std::optional<Location> previousLocation;
111
112
bool operator==(const DuplicateTypeDefinition& rhs) const;
113
};
114
115
struct CountMismatch
116
{
117
enum Context
118
{
119
Arg,
120
FunctionResult,
121
ExprListResult,
122
Return,
123
};
124
size_t expected;
125
std::optional<size_t> maximum;
126
size_t actual;
127
Context context = Arg;
128
bool isVariadic = false;
129
std::string function;
130
131
bool operator==(const CountMismatch& rhs) const;
132
};
133
134
struct FunctionDoesNotTakeSelf
135
{
136
bool operator==(const FunctionDoesNotTakeSelf& rhs) const;
137
};
138
139
struct FunctionRequiresSelf
140
{
141
bool operator==(const FunctionRequiresSelf& rhs) const;
142
};
143
144
struct OccursCheckFailed
145
{
146
bool operator==(const OccursCheckFailed& rhs) const;
147
};
148
149
struct UnknownRequire
150
{
151
std::string modulePath;
152
153
bool operator==(const UnknownRequire& rhs) const;
154
};
155
156
struct IncorrectGenericParameterCount
157
{
158
Name name;
159
TypeFun typeFun;
160
size_t actualParameters;
161
size_t actualPackParameters;
162
163
bool operator==(const IncorrectGenericParameterCount& rhs) const;
164
};
165
166
struct SyntaxError
167
{
168
std::string message;
169
170
bool operator==(const SyntaxError& rhs) const;
171
};
172
173
struct CodeTooComplex
174
{
175
bool operator==(const CodeTooComplex&) const;
176
};
177
178
struct UnificationTooComplex
179
{
180
bool operator==(const UnificationTooComplex&) const;
181
};
182
183
// Could easily be folded into UnknownProperty with an extra field, std::set<Name> candidates.
184
// But for telemetry purposes, we want to have this be a distinct variant.
185
struct UnknownPropButFoundLikeProp
186
{
187
TypeId table;
188
Name key;
189
std::set<Name> candidates;
190
191
bool operator==(const UnknownPropButFoundLikeProp& rhs) const;
192
};
193
194
struct GenericError
195
{
196
std::string message;
197
198
bool operator==(const GenericError& rhs) const;
199
};
200
201
struct InternalError
202
{
203
std::string message;
204
205
bool operator==(const InternalError& rhs) const;
206
};
207
208
struct ConstraintSolvingIncompleteError
209
{
210
bool operator==(const ConstraintSolvingIncompleteError& rhs) const;
211
};
212
213
struct CannotCallNonFunction
214
{
215
TypeId ty;
216
217
bool operator==(const CannotCallNonFunction& rhs) const;
218
};
219
220
struct ExtraInformation
221
{
222
std::string message;
223
bool operator==(const ExtraInformation& rhs) const;
224
};
225
226
struct DeprecatedApiUsed
227
{
228
std::string symbol;
229
std::string useInstead;
230
bool operator==(const DeprecatedApiUsed& rhs) const;
231
};
232
233
struct ModuleHasCyclicDependency
234
{
235
std::vector<ModuleName> cycle;
236
bool operator==(const ModuleHasCyclicDependency& rhs) const;
237
};
238
239
struct FunctionExitsWithoutReturning
240
{
241
TypePackId expectedReturnType;
242
bool operator==(const FunctionExitsWithoutReturning& rhs) const;
243
};
244
245
struct IllegalRequire
246
{
247
std::string moduleName;
248
std::string reason;
249
250
bool operator==(const IllegalRequire& rhs) const;
251
};
252
253
struct MissingProperties
254
{
255
enum Context
256
{
257
Missing,
258
Extra
259
};
260
TypeId superType;
261
TypeId subType;
262
std::vector<Name> properties;
263
Context context = Missing;
264
265
bool operator==(const MissingProperties& rhs) const;
266
};
267
268
struct DuplicateGenericParameter
269
{
270
std::string parameterName;
271
272
bool operator==(const DuplicateGenericParameter& rhs) const;
273
};
274
275
struct CannotInferBinaryOperation
276
{
277
enum OpKind
278
{
279
Operation,
280
Comparison,
281
};
282
283
AstExprBinary::Op op;
284
std::optional<std::string> suggestedToAnnotate;
285
OpKind kind;
286
287
bool operator==(const CannotInferBinaryOperation& rhs) const;
288
};
289
290
struct SwappedGenericTypeParameter
291
{
292
enum Kind
293
{
294
Type,
295
Pack,
296
};
297
298
std::string name;
299
// What was `name` being used as?
300
Kind kind;
301
302
bool operator==(const SwappedGenericTypeParameter& rhs) const;
303
};
304
305
struct OptionalValueAccess
306
{
307
TypeId optional;
308
309
bool operator==(const OptionalValueAccess& rhs) const;
310
};
311
312
struct MissingUnionProperty
313
{
314
TypeId type;
315
std::vector<TypeId> missing;
316
Name key;
317
318
bool operator==(const MissingUnionProperty& rhs) const;
319
};
320
321
struct TypesAreUnrelated
322
{
323
TypeId left;
324
TypeId right;
325
326
bool operator==(const TypesAreUnrelated& rhs) const;
327
};
328
329
struct NormalizationTooComplex
330
{
331
bool operator==(const NormalizationTooComplex&) const
332
{
333
return true;
334
}
335
};
336
337
struct TypePackMismatch
338
{
339
TypePackId wantedTp;
340
TypePackId givenTp;
341
std::string reason;
342
343
bool operator==(const TypePackMismatch& rhs) const;
344
};
345
346
struct DynamicPropertyLookupOnExternTypesUnsafe
347
{
348
TypeId ty;
349
350
bool operator==(const DynamicPropertyLookupOnExternTypesUnsafe& rhs) const;
351
};
352
353
struct UninhabitedTypeFunction
354
{
355
TypeId ty;
356
357
bool operator==(const UninhabitedTypeFunction& rhs) const;
358
};
359
360
struct ExplicitFunctionAnnotationRecommended
361
{
362
std::vector<std::pair<std::string, TypeId>> recommendedArgs;
363
TypeId recommendedReturn;
364
bool operator==(const ExplicitFunctionAnnotationRecommended& rhs) const;
365
};
366
367
struct UninhabitedTypePackFunction
368
{
369
TypePackId tp;
370
371
bool operator==(const UninhabitedTypePackFunction& rhs) const;
372
};
373
374
struct WhereClauseNeeded
375
{
376
TypeId ty;
377
378
bool operator==(const WhereClauseNeeded& rhs) const;
379
};
380
381
struct PackWhereClauseNeeded
382
{
383
TypePackId tp;
384
385
bool operator==(const PackWhereClauseNeeded& rhs) const;
386
};
387
388
struct CheckedFunctionCallError
389
{
390
TypeId expected;
391
TypeId passed;
392
std::string checkedFunctionName;
393
// TODO: make this a vector<argumentIndices>
394
size_t argumentIndex;
395
bool operator==(const CheckedFunctionCallError& rhs) const;
396
};
397
398
struct NonStrictFunctionDefinitionError
399
{
400
std::string functionName;
401
std::string argument;
402
TypeId argumentType;
403
bool operator==(const NonStrictFunctionDefinitionError& rhs) const;
404
};
405
406
struct PropertyAccessViolation
407
{
408
TypeId table;
409
Name key;
410
411
enum
412
{
413
CannotRead,
414
CannotWrite
415
} context;
416
417
bool operator==(const PropertyAccessViolation& rhs) const;
418
};
419
420
struct CheckedFunctionIncorrectArgs
421
{
422
std::string functionName;
423
size_t expected;
424
size_t actual;
425
bool operator==(const CheckedFunctionIncorrectArgs& rhs) const;
426
};
427
428
struct CannotAssignToNever
429
{
430
// type of the rvalue being assigned
431
TypeId rhsType;
432
433
// Originating type.
434
std::vector<TypeId> cause;
435
436
enum class Reason
437
{
438
// when assigning to a property in a union of tables, the properties type
439
// is narrowed to the intersection of its type in each variant.
440
PropertyNarrowed,
441
};
442
443
Reason reason;
444
445
bool operator==(const CannotAssignToNever& rhs) const;
446
};
447
448
struct UnexpectedTypeInSubtyping
449
{
450
TypeId ty;
451
452
bool operator==(const UnexpectedTypeInSubtyping& rhs) const;
453
};
454
455
struct UnexpectedTypePackInSubtyping
456
{
457
TypePackId tp;
458
459
bool operator==(const UnexpectedTypePackInSubtyping& rhs) const;
460
};
461
462
struct UserDefinedTypeFunctionError
463
{
464
std::string message;
465
466
bool operator==(const UserDefinedTypeFunctionError& rhs) const;
467
};
468
469
struct BuiltInTypeFunctionError
470
{
471
TypeFunctionError error;
472
473
bool operator==(const BuiltInTypeFunctionError& rhs) const;
474
};
475
476
struct ReservedIdentifier
477
{
478
std::string name;
479
480
bool operator==(const ReservedIdentifier& rhs) const;
481
};
482
483
struct UnexpectedArrayLikeTableItem
484
{
485
bool operator==(const UnexpectedArrayLikeTableItem&) const
486
{
487
return true;
488
}
489
};
490
491
struct CannotCheckDynamicStringFormatCalls
492
{
493
bool operator==(const CannotCheckDynamicStringFormatCalls&) const
494
{
495
return true;
496
}
497
};
498
499
// Error during subtyping when the number of generic types between compared types does not match
500
struct GenericTypeCountMismatch
501
{
502
size_t subTyGenericCount;
503
size_t superTyGenericCount;
504
505
bool operator==(const GenericTypeCountMismatch& rhs) const;
506
};
507
508
// Error during subtyping when the number of generic type packs between compared types does not match
509
struct GenericTypePackCountMismatch
510
{
511
size_t subTyGenericPackCount;
512
size_t superTyGenericPackCount;
513
514
bool operator==(const GenericTypePackCountMismatch& rhs) const;
515
};
516
517
// Error during subtyping when the number of generic type packs between compared types does not match
518
struct MultipleNonviableOverloads
519
{
520
size_t attemptedArgCount;
521
522
bool operator==(const MultipleNonviableOverloads& rhs) const;
523
};
524
525
// Error where a type alias violates the recursive restraint, ie when a type alias T<A> has T with different arguments on the RHS.
526
struct RecursiveRestraintViolation
527
{
528
bool operator==(const RecursiveRestraintViolation& rhs) const
529
{
530
return true;
531
}
532
};
533
534
// Error during subtyping when the inferred bounds of a generic type are incompatible
535
struct GenericBoundsMismatch
536
{
537
std::string_view genericName;
538
std::vector<TypeId> lowerBounds;
539
std::vector<TypeId> upperBounds;
540
541
GenericBoundsMismatch(std::string_view genericName, TypeIds lowerBoundSet, TypeIds upperBoundSet);
542
543
bool operator==(const GenericBoundsMismatch& rhs) const;
544
};
545
546
// Used `f<<T>>` where f is not a function
547
struct InstantiateGenericsOnNonFunction
548
{
549
enum class InterestingEdgeCase
550
{
551
None,
552
MetatableCall,
553
Intersection,
554
};
555
556
InterestingEdgeCase interestingEdgeCase;
557
558
bool operator==(const InstantiateGenericsOnNonFunction&) const;
559
};
560
561
// Provided too many generics inside `f<<T>>`
562
struct TypeInstantiationCountMismatch
563
{
564
std::optional<std::string> functionName;
565
TypeId functionType;
566
567
size_t providedTypes = 0;
568
size_t maximumTypes = 0;
569
570
size_t providedTypePacks = 0;
571
size_t maximumTypePacks = 0;
572
573
bool operator==(const TypeInstantiationCountMismatch&) const;
574
};
575
576
// Error when referencing a type function without providing explicit generics.
577
//
578
// type function create_table_with_key()
579
// local tbl = types.newtable()
580
// tbl:setproperty(types.singleton "key", types.unionof(types.string, types.singleton(nil)))
581
// return tbl
582
// end
583
// local a: create_table_with_key = {}
584
// ^^^^^^^^^^^^^^^^^^^^^ This should have `<>` at the end.
585
//
586
struct UnappliedTypeFunction
587
{
588
bool operator==(const UnappliedTypeFunction& rhs) const;
589
};
590
591
// Error when we have an ambiguous overload and cannot determine the correct
592
// function call.
593
//
594
// local f: ((number | string) -> "one") & ((number | boolean) -> "two")
595
// local g = f(42)
596
// ^^^^^ We cannot determine the correct call here
597
struct AmbiguousFunctionCall
598
{
599
TypeId function;
600
TypePackId arguments;
601
602
bool operator==(const AmbiguousFunctionCall& rhs) const;
603
};
604
605
using TypeErrorData = Variant<
606
TypeMismatch,
607
UnknownSymbol,
608
UnknownProperty,
609
NotATable,
610
CannotExtendTable,
611
CannotCompareUnrelatedTypes,
612
OnlyTablesCanHaveMethods,
613
DuplicateTypeDefinition,
614
CountMismatch,
615
FunctionDoesNotTakeSelf,
616
FunctionRequiresSelf,
617
OccursCheckFailed,
618
UnknownRequire,
619
IncorrectGenericParameterCount,
620
SyntaxError,
621
CodeTooComplex,
622
UnificationTooComplex,
623
UnknownPropButFoundLikeProp,
624
GenericError,
625
InternalError,
626
ConstraintSolvingIncompleteError,
627
CannotCallNonFunction,
628
ExtraInformation,
629
DeprecatedApiUsed,
630
ModuleHasCyclicDependency,
631
IllegalRequire,
632
FunctionExitsWithoutReturning,
633
DuplicateGenericParameter,
634
CannotAssignToNever,
635
CannotInferBinaryOperation,
636
MissingProperties,
637
SwappedGenericTypeParameter,
638
OptionalValueAccess,
639
MissingUnionProperty,
640
TypesAreUnrelated,
641
NormalizationTooComplex,
642
TypePackMismatch,
643
DynamicPropertyLookupOnExternTypesUnsafe,
644
UninhabitedTypeFunction,
645
UninhabitedTypePackFunction,
646
WhereClauseNeeded,
647
PackWhereClauseNeeded,
648
CheckedFunctionCallError,
649
NonStrictFunctionDefinitionError,
650
PropertyAccessViolation,
651
CheckedFunctionIncorrectArgs,
652
UnexpectedTypeInSubtyping,
653
UnexpectedTypePackInSubtyping,
654
ExplicitFunctionAnnotationRecommended,
655
UserDefinedTypeFunctionError,
656
BuiltInTypeFunctionError,
657
ReservedIdentifier,
658
UnexpectedArrayLikeTableItem,
659
CannotCheckDynamicStringFormatCalls,
660
GenericTypeCountMismatch,
661
GenericTypePackCountMismatch,
662
MultipleNonviableOverloads,
663
RecursiveRestraintViolation,
664
GenericBoundsMismatch,
665
UnappliedTypeFunction,
666
InstantiateGenericsOnNonFunction,
667
TypeInstantiationCountMismatch,
668
AmbiguousFunctionCall>;
669
670
struct TypeErrorSummary
671
{
672
Location location;
673
ModuleName moduleName;
674
int code;
675
676
TypeErrorSummary(const Location& location, const ModuleName& moduleName, int code)
677
: location(location)
678
, moduleName(moduleName)
679
, code(code)
680
{
681
}
682
};
683
684
struct TypeError
685
{
686
Location location;
687
ModuleName moduleName;
688
TypeErrorData data;
689
690
static int minCode();
691
int code() const;
692
693
TypeError() = default;
694
695
TypeError(const Location& location, const ModuleName& moduleName, const TypeErrorData& data)
696
: location(location)
697
, moduleName(moduleName)
698
, data(data)
699
{
700
}
701
702
TypeError(const Location& location, const TypeErrorData& data)
703
: TypeError(location, {}, data)
704
{
705
}
706
707
bool operator==(const TypeError& rhs) const;
708
709
TypeErrorSummary summary() const;
710
};
711
712
template<typename T>
713
const T* get(const TypeError& e)
714
{
715
return get_if<T>(&e.data);
716
}
717
718
template<typename T>
719
T* get(TypeError& e)
720
{
721
return get_if<T>(&e.data);
722
}
723
724
using ErrorVec = std::vector<TypeError>;
725
726
struct TypeErrorToStringOptions
727
{
728
FileResolver* fileResolver = nullptr;
729
};
730
731
std::string toString(const TypeError& error);
732
std::string toString(const TypeError& error, TypeErrorToStringOptions options);
733
734
bool containsParseErrorName(const TypeError& error);
735
736
// Copy any types named in the error into destArena.
737
void copyErrors(ErrorVec& errors, struct TypeArena& destArena, NotNull<BuiltinTypes> builtinTypes);
738
739
// Internal Compiler Error
740
struct InternalErrorReporter
741
{
742
std::function<void(const char*)> onInternalError;
743
std::string moduleName;
744
745
[[noreturn]] void ice(const std::string& message, const Location& location) const;
746
[[noreturn]] void ice(const std::string& message) const;
747
};
748
749
class InternalCompilerError : public std::exception
750
{
751
public:
752
explicit InternalCompilerError(const std::string& message)
753
: message(message)
754
{
755
}
756
explicit InternalCompilerError(const std::string& message, const std::string& moduleName)
757
: message(message)
758
, moduleName(moduleName)
759
{
760
}
761
explicit InternalCompilerError(const std::string& message, const std::string& moduleName, const Location& location)
762
: message(message)
763
, moduleName(moduleName)
764
, location(location)
765
{
766
}
767
const char* what() const throw() override;
768
769
const std::string message;
770
const std::optional<std::string> moduleName;
771
const std::optional<Location> location;
772
};
773
774
} // namespace Luau
775
776