@@ -31,53 +31,33 @@ abstract class TypeMention extends AstNode {
31
31
Type resolveTypeAt ( TypePath path ) { result = this .getMentionAt ( path ) .resolveType ( ) }
32
32
}
33
33
34
- class TypeReprMention extends TypeMention , TypeRepr {
35
- TypeReprMention ( ) { not this instanceof InferTypeRepr }
34
+ class ArrayTypeReprMention extends TypeMention instanceof ArrayTypeRepr {
35
+ override TypeMention getTypeArgument ( int i ) { result = super . getElementTypeRepr ( ) and i = 0 }
36
36
37
- override TypeReprMention getTypeArgument ( int i ) {
38
- result = this .( ArrayTypeRepr ) .getElementTypeRepr ( ) and
39
- i = 0
40
- or
41
- result = this .( RefTypeRepr ) .getTypeRepr ( ) and
42
- i = 0
43
- or
44
- result = this .( PathTypeRepr ) .getPath ( ) .( PathMention ) .getTypeArgument ( i )
45
- }
37
+ override Type resolveType ( ) { result = TArrayType ( ) }
38
+ }
46
39
47
- override Type resolveType ( ) {
48
- this instanceof ArrayTypeRepr and
49
- result = TArrayType ( )
50
- or
51
- this instanceof RefTypeRepr and
52
- result = TRefType ( )
53
- or
54
- result = this .( PathTypeRepr ) .getPath ( ) .( PathMention ) .resolveType ( )
55
- }
40
+ class RefTypeReprMention extends TypeMention instanceof RefTypeRepr {
41
+ override TypeMention getTypeArgument ( int i ) { result = super .getTypeRepr ( ) and i = 0 }
56
42
57
- override Type resolveTypeAt ( TypePath path ) {
58
- result = this .( PathTypeRepr ) .getPath ( ) .( PathMention ) .resolveTypeAt ( path )
59
- or
60
- not exists ( this .( PathTypeRepr ) .getPath ( ) ) and
61
- result = super .resolveTypeAt ( path )
62
- }
43
+ override Type resolveType ( ) { result = TRefType ( ) }
63
44
}
64
45
65
- /** Holds if `path` resolves to the type alias `alias` with the definition `rhs`. */
66
- private predicate resolvePathAlias ( Path path , TypeAlias alias , TypeReprMention rhs ) {
67
- alias = resolvePath ( path ) and rhs = alias .getTypeRepr ( )
68
- }
46
+ class PathTypeReprMention extends TypeMention instanceof PathTypeRepr {
47
+ Path path ;
48
+ ItemNode resolved ;
69
49
70
- abstract class PathMention extends TypeMention , Path {
71
- override TypeMention getTypeArgument ( int i ) {
72
- result = this .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( i )
50
+ PathTypeReprMention ( ) {
51
+ path = super .getPath ( ) and
52
+ // NOTE: This excludes unresolvable paths which is intentional as these
53
+ // don't add value to the type inference anyway.
54
+ resolved = resolvePath ( path )
73
55
}
74
- }
75
56
76
- class NonAliasPathMention extends PathMention {
77
- NonAliasPathMention ( ) { not resolvePathAlias ( this , _, _) }
57
+ ItemNode getResolved ( ) { result = resolved }
78
58
79
59
override TypeMention getTypeArgument ( int i ) {
80
- result = super . getTypeArgument ( i )
60
+ result = path . getSegment ( ) . getGenericArgList ( ) . getTypeArg ( i )
81
61
or
82
62
// `Self` paths inside `impl` blocks have implicit type arguments that are
83
63
// the type parameters of the `impl` block. For example, in
@@ -92,106 +72,112 @@ class NonAliasPathMention extends PathMention {
92
72
//
93
73
// the `Self` return type is shorthand for `Foo<T>`.
94
74
exists ( ImplItemNode node |
95
- this = node .getASelfPath ( ) and
75
+ path = node .getASelfPath ( ) and
96
76
result = node .( ImplItemNode ) .getSelfPath ( ) .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( i )
97
77
)
98
78
or
99
- // If `this ` is the trait of an `impl` block then any associated types
79
+ // If `path ` is the trait of an `impl` block then any associated types
100
80
// defined in the `impl` block are type arguments to the trait.
101
81
//
102
82
// For instance, for a trait implementation like this
103
83
// ```rust
104
84
// impl MyTrait for MyType {
105
- // ^^^^^^^ this
85
+ // ^^^^^^^ path
106
86
// type AssociatedType = i64
107
87
// ^^^ result
108
88
// // ...
109
89
// }
110
90
// ```
111
91
// the rhs. of the type alias is a type argument to the trait.
112
92
exists ( ImplItemNode impl , AssociatedTypeTypeParameter param , TypeAlias alias |
113
- this = impl .getTraitPath ( ) and
114
- param .getTrait ( ) = resolvePath ( this ) and
93
+ path = impl .getTraitPath ( ) and
94
+ param .getTrait ( ) = resolved and
115
95
alias = impl .getASuccessor ( param .getTypeAlias ( ) .getName ( ) .getText ( ) ) and
116
96
result = alias .getTypeRepr ( ) and
117
97
param .getIndex ( ) = i
118
98
)
119
99
}
120
100
101
+ /**
102
+ * Holds if this path resolved to a type alias with a rhs. that has the
103
+ * resulting type at `typePath`.
104
+ */
105
+ Type aliasResolveTypeAt ( TypePath typePath ) {
106
+ exists ( TypeAlias alias , TypeMention rhs | alias = resolved and rhs = alias .getTypeRepr ( ) |
107
+ result = rhs .resolveTypeAt ( typePath ) and
108
+ not result = pathGetTypeParameter ( alias , _)
109
+ or
110
+ exists ( TypeParameter tp , TypeMention arg , TypePath prefix , TypePath suffix , int i |
111
+ tp = rhs .resolveTypeAt ( prefix ) and
112
+ tp = pathGetTypeParameter ( alias , i ) and
113
+ arg = path .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( i ) and
114
+ result = arg .resolveTypeAt ( suffix ) and
115
+ typePath = prefix .append ( suffix )
116
+ )
117
+ )
118
+ }
119
+
121
120
override Type resolveType ( ) {
122
- exists ( ItemNode i | i = resolvePath ( this ) |
123
- result = TStruct ( i )
121
+ result = this .aliasResolveTypeAt ( TypePath:: nil ( ) )
122
+ or
123
+ not exists ( resolved .( TypeAlias ) .getTypeRepr ( ) ) and
124
+ (
125
+ result = TStruct ( resolved )
124
126
or
125
- result = TEnum ( i )
127
+ result = TEnum ( resolved )
126
128
or
127
- exists ( TraitItemNode trait | trait = i |
129
+ exists ( TraitItemNode trait | trait = resolved |
128
130
// If this is a `Self` path, then it resolves to the implicit `Self`
129
131
// type parameter, otherwise it is a trait bound.
130
- if this = trait .getASelfPath ( )
132
+ if super . getPath ( ) = trait .getASelfPath ( )
131
133
then result = TSelfTypeParameter ( trait )
132
134
else result = TTrait ( trait )
133
135
)
134
136
or
135
- result = TTypeParamTypeParameter ( i )
137
+ result = TTypeParamTypeParameter ( resolved )
136
138
or
137
- exists ( TypeAlias alias | alias = i |
139
+ exists ( TypeAlias alias | alias = resolved |
138
140
result .( AssociatedTypeTypeParameter ) .getTypeAlias ( ) = alias
139
141
or
140
- result = alias .getTypeRepr ( ) .( TypeReprMention ) .resolveType ( )
142
+ result = alias .getTypeRepr ( ) .( TypeMention ) .resolveType ( )
141
143
)
142
144
)
143
145
}
144
- }
145
-
146
- class AliasPathMention extends PathMention {
147
- TypeAlias alias ;
148
- TypeReprMention rhs ;
149
-
150
- AliasPathMention ( ) { resolvePathAlias ( this , alias , rhs ) }
151
-
152
- /** Get the `i`th type parameter of the alias itself. */
153
- private TypeParameter getTypeParameter ( int i ) {
154
- result = TTypeParamTypeParameter ( alias .getGenericParamList ( ) .getTypeParam ( i ) )
155
- }
156
-
157
- override Type resolveType ( ) { result = rhs .resolveType ( ) }
158
146
159
- override Type resolveTypeAt ( TypePath path ) {
160
- result = rhs .resolveTypeAt ( path ) and
161
- not result = this .getTypeParameter ( _)
147
+ override Type resolveTypeAt ( TypePath typePath ) {
148
+ result = this .aliasResolveTypeAt ( typePath )
162
149
or
163
- exists ( TypeParameter tp , TypeMention arg , TypePath prefix , TypePath suffix , int i |
164
- tp = rhs .resolveTypeAt ( prefix ) and
165
- tp = this .getTypeParameter ( i ) and
166
- arg = this .getTypeArgument ( i ) and
167
- result = arg .resolveTypeAt ( suffix ) and
168
- path = prefix .append ( suffix )
169
- )
150
+ not exists ( resolved .( TypeAlias ) .getTypeRepr ( ) ) and
151
+ result = super .resolveTypeAt ( typePath )
170
152
}
171
153
}
172
154
155
+ private TypeParameter pathGetTypeParameter ( TypeAlias alias , int i ) {
156
+ result = TTypeParamTypeParameter ( alias .getGenericParamList ( ) .getTypeParam ( i ) )
157
+ }
158
+
173
159
// Used to represent implicit `Self` type arguments in traits and `impl` blocks,
174
160
// see `PathMention` for details.
175
- class TypeParamMention extends TypeMention , TypeParam {
176
- override TypeReprMention getTypeArgument ( int i ) { none ( ) }
161
+ class TypeParamMention extends TypeMention instanceof TypeParam {
162
+ override TypeMention getTypeArgument ( int i ) { none ( ) }
177
163
178
164
override Type resolveType ( ) { result = TTypeParamTypeParameter ( this ) }
179
165
}
180
166
181
167
// Used to represent implicit type arguments for associated types in traits.
182
- class TypeAliasMention extends TypeMention , TypeAlias {
168
+ class TypeAliasMention extends TypeMention instanceof TypeAlias {
183
169
private Type t ;
184
170
185
171
TypeAliasMention ( ) { t = TAssociatedTypeTypeParameter ( this ) }
186
172
187
- override TypeReprMention getTypeArgument ( int i ) { none ( ) }
173
+ override TypeMention getTypeArgument ( int i ) { none ( ) }
188
174
189
175
override Type resolveType ( ) { result = t }
190
176
}
191
177
192
- class TraitMention extends TypeMention , TraitItemNode {
178
+ class TraitMention extends TypeMention instanceof TraitItemNode {
193
179
override TypeMention getTypeArgument ( int i ) {
194
- result = this .getTypeParam ( i )
180
+ result = super .getTypeParam ( i )
195
181
or
196
182
traitAliasIndex ( this , i , result )
197
183
}
@@ -203,7 +189,7 @@ class TraitMention extends TypeMention, TraitItemNode {
203
189
// appears in the AST, we (somewhat arbitrarily) choose the name of a trait as a
204
190
// type mention. This works because there is a one-to-one correspondence between
205
191
// a trait and its name.
206
- class SelfTypeParameterMention extends TypeMention , Name {
192
+ class SelfTypeParameterMention extends TypeMention instanceof Name {
207
193
Trait trait ;
208
194
209
195
SelfTypeParameterMention ( ) { trait .getName ( ) = this }
@@ -212,5 +198,5 @@ class SelfTypeParameterMention extends TypeMention, Name {
212
198
213
199
override Type resolveType ( ) { result = TSelfTypeParameter ( trait ) }
214
200
215
- override TypeReprMention getTypeArgument ( int i ) { none ( ) }
201
+ override TypeMention getTypeArgument ( int i ) { none ( ) }
216
202
}
0 commit comments