@@ -31,53 +31,33 @@ abstract class TypeMention extends AstNode {
3131 Type resolveTypeAt ( TypePath path ) { result = this .getMentionAt ( path ) .resolveType ( ) }
3232}
3333
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 }
3636
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+ }
4639
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 }
5642
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 ( ) }
6344}
6445
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 ;
6949
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 )
7355 }
74- }
7556
76- class NonAliasPathMention extends PathMention {
77- NonAliasPathMention ( ) { not resolvePathAlias ( this , _, _) }
57+ ItemNode getResolved ( ) { result = resolved }
7858
7959 override TypeMention getTypeArgument ( int i ) {
80- result = super . getTypeArgument ( i )
60+ result = path . getSegment ( ) . getGenericArgList ( ) . getTypeArg ( i )
8161 or
8262 // `Self` paths inside `impl` blocks have implicit type arguments that are
8363 // the type parameters of the `impl` block. For example, in
@@ -92,106 +72,112 @@ class NonAliasPathMention extends PathMention {
9272 //
9373 // the `Self` return type is shorthand for `Foo<T>`.
9474 exists ( ImplItemNode node |
95- this = node .getASelfPath ( ) and
75+ path = node .getASelfPath ( ) and
9676 result = node .( ImplItemNode ) .getSelfPath ( ) .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( i )
9777 )
9878 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
10080 // defined in the `impl` block are type arguments to the trait.
10181 //
10282 // For instance, for a trait implementation like this
10383 // ```rust
10484 // impl MyTrait for MyType {
105- // ^^^^^^^ this
85+ // ^^^^^^^ path
10686 // type AssociatedType = i64
10787 // ^^^ result
10888 // // ...
10989 // }
11090 // ```
11191 // the rhs. of the type alias is a type argument to the trait.
11292 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
11595 alias = impl .getASuccessor ( param .getTypeAlias ( ) .getName ( ) .getText ( ) ) and
11696 result = alias .getTypeRepr ( ) and
11797 param .getIndex ( ) = i
11898 )
11999 }
120100
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+
121120 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 )
124126 or
125- result = TEnum ( i )
127+ result = TEnum ( resolved )
126128 or
127- exists ( TraitItemNode trait | trait = i |
129+ exists ( TraitItemNode trait | trait = resolved |
128130 // If this is a `Self` path, then it resolves to the implicit `Self`
129131 // type parameter, otherwise it is a trait bound.
130- if this = trait .getASelfPath ( )
132+ if super . getPath ( ) = trait .getASelfPath ( )
131133 then result = TSelfTypeParameter ( trait )
132134 else result = TTrait ( trait )
133135 )
134136 or
135- result = TTypeParamTypeParameter ( i )
137+ result = TTypeParamTypeParameter ( resolved )
136138 or
137- exists ( TypeAlias alias | alias = i |
139+ exists ( TypeAlias alias | alias = resolved |
138140 result .( AssociatedTypeTypeParameter ) .getTypeAlias ( ) = alias
139141 or
140- result = alias .getTypeRepr ( ) .( TypeReprMention ) .resolveType ( )
142+ result = alias .getTypeRepr ( ) .( TypeMention ) .resolveType ( )
141143 )
142144 )
143145 }
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 ( ) }
158146
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 )
162149 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 )
170152 }
171153}
172154
155+ private TypeParameter pathGetTypeParameter ( TypeAlias alias , int i ) {
156+ result = TTypeParamTypeParameter ( alias .getGenericParamList ( ) .getTypeParam ( i ) )
157+ }
158+
173159// Used to represent implicit `Self` type arguments in traits and `impl` blocks,
174160// 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 ( ) }
177163
178164 override Type resolveType ( ) { result = TTypeParamTypeParameter ( this ) }
179165}
180166
181167// Used to represent implicit type arguments for associated types in traits.
182- class TypeAliasMention extends TypeMention , TypeAlias {
168+ class TypeAliasMention extends TypeMention instanceof TypeAlias {
183169 private Type t ;
184170
185171 TypeAliasMention ( ) { t = TAssociatedTypeTypeParameter ( this ) }
186172
187- override TypeReprMention getTypeArgument ( int i ) { none ( ) }
173+ override TypeMention getTypeArgument ( int i ) { none ( ) }
188174
189175 override Type resolveType ( ) { result = t }
190176}
191177
192- class TraitMention extends TypeMention , TraitItemNode {
178+ class TraitMention extends TypeMention instanceof TraitItemNode {
193179 override TypeMention getTypeArgument ( int i ) {
194- result = this .getTypeParam ( i )
180+ result = super .getTypeParam ( i )
195181 or
196182 traitAliasIndex ( this , i , result )
197183 }
@@ -203,7 +189,7 @@ class TraitMention extends TypeMention, TraitItemNode {
203189// appears in the AST, we (somewhat arbitrarily) choose the name of a trait as a
204190// type mention. This works because there is a one-to-one correspondence between
205191// a trait and its name.
206- class SelfTypeParameterMention extends TypeMention , Name {
192+ class SelfTypeParameterMention extends TypeMention instanceof Name {
207193 Trait trait ;
208194
209195 SelfTypeParameterMention ( ) { trait .getName ( ) = this }
@@ -212,5 +198,5 @@ class SelfTypeParameterMention extends TypeMention, Name {
212198
213199 override Type resolveType ( ) { result = TSelfTypeParameter ( trait ) }
214200
215- override TypeReprMention getTypeArgument ( int i ) { none ( ) }
201+ override TypeMention getTypeArgument ( int i ) { none ( ) }
216202}
0 commit comments