@@ -86,17 +86,13 @@ type ErrorOutputContainer struct {
86
86
87
87
type ErrorReporter func (message * diagnostics.Message , args ... any )
88
88
89
- type RecursionIdKind uint32
90
-
91
- const (
92
- RecursionIdKindNode RecursionIdKind = iota
93
- RecursionIdKindSymbol
94
- RecursionIdKindType
95
- )
96
-
97
89
type RecursionId struct {
98
- kind RecursionIdKind
99
- id uint32
90
+ value any
91
+ }
92
+
93
+ // This function exists to constrain the types of values that can be used as recursion IDs.
94
+ func asRecursionId [T * ast.Node | * ast.Symbol | * Type ](value T ) RecursionId {
95
+ return RecursionId {value : value }
100
96
}
101
97
102
98
type Relation struct {
@@ -836,35 +832,35 @@ func getRecursionIdentity(t *Type) RecursionId {
836
832
// Deferred type references are tracked through their associated AST node. This gives us finer
837
833
// granularity than using their associated target because each manifest type reference has a
838
834
// unique AST node.
839
- return RecursionId { kind : RecursionIdKindNode , id : uint32 ( ast . GetNodeId ( t .AsTypeReference ().node ))}
835
+ return asRecursionId ( t .AsTypeReference ().node )
840
836
}
841
837
if t .symbol != nil && ! (t .objectFlags & ObjectFlagsAnonymous != 0 && t .symbol .Flags & ast .SymbolFlagsClass != 0 ) {
842
838
// We track object types that have a symbol by that symbol (representing the origin of the type), but
843
839
// exclude the static side of a class since it shares its symbol with the instance side.
844
- return RecursionId { kind : RecursionIdKindSymbol , id : uint32 ( ast . GetSymbolId ( t .symbol ))}
840
+ return asRecursionId ( t .symbol )
845
841
}
846
842
if isTupleType (t ) {
847
- return RecursionId { kind : RecursionIdKindType , id : uint32 (t .Target (). id )}
843
+ return asRecursionId (t .Target ())
848
844
}
849
845
}
850
846
if t .flags & TypeFlagsTypeParameter != 0 && t .symbol != nil {
851
847
// We use the symbol of the type parameter such that all "fresh" instantiations of that type parameter
852
848
// have the same recursion identity.
853
- return RecursionId { kind : RecursionIdKindSymbol , id : uint32 ( ast . GetSymbolId ( t .symbol ))}
849
+ return asRecursionId ( t .symbol )
854
850
}
855
851
if t .flags & TypeFlagsIndexedAccess != 0 {
856
852
// Identity is the leftmost object type in a chain of indexed accesses, eg, in A[P1][P2][P3] it is A.
857
853
t = t .AsIndexedAccessType ().objectType
858
854
for t .flags & TypeFlagsIndexedAccess != 0 {
859
855
t = t .AsIndexedAccessType ().objectType
860
856
}
861
- return RecursionId { kind : RecursionIdKindType , id : uint32 ( t . id )}
857
+ return asRecursionId ( t )
862
858
}
863
859
if t .flags & TypeFlagsConditional != 0 {
864
860
// The root object represents the origin of the conditional type
865
- return RecursionId { kind : RecursionIdKindNode , id : uint32 ( ast . GetNodeId ( t .AsConditionalType ().root .node .AsNode ()))}
861
+ return asRecursionId ( t .AsConditionalType ().root .node .AsNode ())
866
862
}
867
- return RecursionId { kind : RecursionIdKindType , id : uint32 ( t . id )}
863
+ return asRecursionId ( t )
868
864
}
869
865
870
866
func (c * Checker ) getBestMatchingType (source * Type , target * Type , isRelatedTo func (source * Type , target * Type ) Ternary ) * Type {
0 commit comments