@@ -50,24 +50,70 @@ class SliceTypeReprMention extends TypeMention instanceof SliceTypeRepr {
5050 }
5151}
5252
53- class PathTypeMention extends TypeMention , Path {
54- TypeItemNode resolved ;
53+ /** Holds if `path` is used as a type mention during type inference. */
54+ predicate relevantPathTypeMention ( Path path ) {
55+ path =
56+ [
57+ any ( PathTypeRepr r ) .getPath ( ) ,
58+ any ( StructExpr s ) .getPath ( ) .getQualifier * ( ) ,
59+ any ( CallExpr ce ) .getFunction ( ) .( PathExpr ) .getPath ( ) .getQualifier * ( ) ,
60+ any ( StructPat p ) .getPath ( ) ,
61+ any ( TupleStructPat p ) .getPath ( )
62+ ]
63+ }
64+
65+ abstract class PathTypeMention extends TypeMention , Path {
66+ PathTypeMention ( ) { relevantPathTypeMention ( this ) }
67+ }
68+
69+ class AliasPathTypeMention extends PathTypeMention {
70+ TypeAlias resolved ;
71+ TypeMention rhs ;
72+
73+ AliasPathTypeMention ( ) {
74+ resolved = resolvePath ( this ) and
75+ rhs = resolved .getTypeRepr ( )
76+ }
77+
78+ TypeItemNode getResolved ( ) { result = resolved }
5579
56- PathTypeMention ( ) {
57- resolved = resolvePath ( this )
80+ /**
81+ * Holds if this path resolved to a type alias with a rhs. that has the
82+ * resulting type at `typePath`.
83+ */
84+ pragma [ nomagic]
85+ override Type resolveTypeAt ( TypePath typePath ) {
86+ result = rhs .resolveTypeAt ( typePath ) and
87+ not result = pathGetTypeParameter ( resolved , _)
5888 or
59- resolved = resolvePath ( this ) .( Variant ) .getEnum ( )
89+ exists ( TypeParameter tp , TypeMention arg , TypePath prefix , TypePath suffix , int i |
90+ tp = rhs .resolveTypeAt ( prefix ) and
91+ tp = pathGetTypeParameter ( resolved , pragma [ only_bind_into ] ( i ) ) and
92+ arg = this .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( pragma [ only_bind_into ] ( i ) ) and
93+ result = arg .resolveTypeAt ( suffix ) and
94+ typePath = prefix .append ( suffix )
95+ )
96+ }
97+ }
98+
99+ class NonAliasPathTypeMention extends PathTypeMention {
100+ TypeItemNode resolved ;
101+
102+ NonAliasPathTypeMention ( ) {
103+ resolved = [ resolvePath ( this ) , resolvePath ( this ) .( Variant ) .getEnum ( ) .( TypeItemNode ) ] and
104+ not exists ( resolved .( TypeAlias ) .getTypeRepr ( ) )
60105 }
61106
62107 TypeItemNode getResolved ( ) { result = resolved }
63108
109+ /**
110+ * Gets a type alias with the name `name` of the trait that this path resolves
111+ * to, if any.
112+ */
64113 pragma [ nomagic]
65114 private TypeAlias getResolvedTraitAlias ( string name ) {
66- exists ( TraitItemNode trait |
67- trait = resolved and
68- result = trait .getAnAssocItem ( ) and
69- name = result .getName ( ) .getText ( )
70- )
115+ result = resolved .( TraitItemNode ) .getAnAssocItem ( ) and
116+ name = result .getName ( ) .getText ( )
71117 }
72118
73119 pragma [ nomagic]
@@ -115,92 +161,75 @@ class PathTypeMention extends TypeMention, Path {
115161 // If a type argument is not given in the path, then we use the default for
116162 // the type parameter if one exists for the type.
117163 not exists ( this .getPositionalTypeArgument0 ( i ) ) and
118- result = this .resolveType ( ) .getTypeParameterDefault ( i ) and
164+ result = this .resolveRootType ( ) .getTypeParameterDefault ( i ) and
119165 // Defaults only apply to type mentions in type annotations
120166 this = any ( PathTypeRepr ptp ) .getPath ( ) .getQualifier * ( )
121167 }
122168
123- /**
124- * Holds if this path resolved to a type alias with a rhs. that has the
125- * resulting type at `typePath`.
126- */
169+ /** Gets the type mention in this path for the type parameter `tp`, if any. */
127170 pragma [ nomagic]
128- private Type aliasResolveTypeAt ( TypePath typePath ) {
129- exists ( TypeAlias alias , TypeMention rhs | alias = resolved and rhs = alias .getTypeRepr ( ) |
130- result = rhs .resolveTypeAt ( typePath ) and
131- not result = pathGetTypeParameter ( alias , _)
132- or
133- exists ( TypeParameter tp , TypeMention arg , TypePath prefix , TypePath suffix , int i |
134- tp = rhs .resolveTypeAt ( prefix ) and
135- tp = pathGetTypeParameter ( alias , pragma [ only_bind_into ] ( i ) ) and
136- arg = this .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( pragma [ only_bind_into ] ( i ) ) and
137- result = arg .resolveTypeAt ( suffix ) and
138- typePath = prefix .append ( suffix )
139- )
171+ private TypeMention getTypeMentionForTypeParameter ( TypeParameter tp ) {
172+ exists ( int i |
173+ result = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) ) and
174+ tp = this .resolveRootType ( ) .getTypeParameter ( pragma [ only_bind_into ] ( i ) )
175+ )
176+ or
177+ exists ( TypeAlias alias |
178+ result = this .getAnAssocTypeArgument ( alias ) and
179+ tp = TAssociatedTypeTypeParameter ( alias )
180+ )
181+ or
182+ // If `path` is the trait of an `impl` block then any associated types
183+ // defined in the `impl` block are type arguments to the trait.
184+ //
185+ // For instance, for a trait implementation like this
186+ // ```rust
187+ // impl MyTrait for MyType {
188+ // ^^^^^^^ path
189+ // type AssociatedType = i64
190+ // ^^^ result
191+ // // ...
192+ // }
193+ // ```
194+ // the rhs. of the type alias is a type argument to the trait.
195+ exists ( ImplItemNode impl , AssociatedTypeTypeParameter param , TypeAlias alias , string name |
196+ this = impl .getTraitPath ( ) and
197+ param .getTrait ( ) = resolved and
198+ name = param .getTypeAlias ( ) .getName ( ) .getText ( ) and
199+ alias = impl .getASuccessor ( pragma [ only_bind_into ] ( name ) ) and
200+ result = alias .getTypeRepr ( ) and
201+ tp =
202+ TAssociatedTypeTypeParameter ( resolved
203+ .( TraitItemNode )
204+ .getAssocItem ( pragma [ only_bind_into ] ( name ) ) )
140205 )
141206 }
142207
143- override Type resolveTypeAt ( TypePath typePath ) {
144- result = this . aliasResolveTypeAt ( typePath )
208+ Type resolveRootType ( ) {
209+ result = TStruct ( resolved )
145210 or
146- typePath .isEmpty ( ) and
147- (
148- result = TStruct ( resolved )
149- or
150- result = TEnum ( resolved )
151- or
152- exists ( TraitItemNode trait | trait = resolved |
153- // If this is a `Self` path, then it resolves to the implicit `Self`
154- // type parameter, otherwise it is a trait bound.
155- if this = trait .getASelfPath ( )
156- then result = TSelfTypeParameter ( trait )
157- else result = TTrait ( trait )
158- )
159- or
160- result = TTypeParamTypeParameter ( resolved )
161- or
162- result = TAssociatedTypeTypeParameter ( resolved )
211+ result = TEnum ( resolved )
212+ or
213+ exists ( TraitItemNode trait | trait = resolved |
214+ // If this is a `Self` path, then it resolves to the implicit `Self`
215+ // type parameter, otherwise it is a trait bound.
216+ if this = trait .getASelfPath ( )
217+ then result = TSelfTypeParameter ( trait )
218+ else result = TTrait ( trait )
163219 )
164220 or
165- not exists ( resolved .( TypeAlias ) .getTypeRepr ( ) ) and
166- exists ( TypeParameter tp , TypeMention arg , TypePath suffix |
167- result = arg .resolveTypeAt ( suffix ) and
221+ result = TTypeParamTypeParameter ( resolved )
222+ or
223+ result = TAssociatedTypeTypeParameter ( resolved )
224+ }
225+
226+ override Type resolveTypeAt ( TypePath typePath ) {
227+ typePath .isEmpty ( ) and
228+ result = this .resolveRootType ( )
229+ or
230+ exists ( TypeParameter tp , TypePath suffix |
231+ result = this .getTypeMentionForTypeParameter ( tp ) .resolveTypeAt ( suffix ) and
168232 typePath = TypePath:: cons ( tp , suffix )
169- |
170- exists ( int i |
171- arg = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) ) and
172- tp = this .resolveType ( ) .getTypeParameter ( pragma [ only_bind_into ] ( i ) )
173- )
174- or
175- exists ( TypeAlias alias |
176- arg = this .getAnAssocTypeArgument ( alias ) and
177- tp = TAssociatedTypeTypeParameter ( alias )
178- )
179- or
180- // If `path` is the trait of an `impl` block then any associated types
181- // defined in the `impl` block are type arguments to the trait.
182- //
183- // For instance, for a trait implementation like this
184- // ```rust
185- // impl MyTrait for MyType {
186- // ^^^^^^^ path
187- // type AssociatedType = i64
188- // ^^^ result
189- // // ...
190- // }
191- // ```
192- // the rhs. of the type alias is a type argument to the trait.
193- exists ( ImplItemNode impl , AssociatedTypeTypeParameter param , TypeAlias alias , string name |
194- this = impl .getTraitPath ( ) and
195- param .getTrait ( ) = resolved and
196- name = param .getTypeAlias ( ) .getName ( ) .getText ( ) and
197- alias = impl .getASuccessor ( pragma [ only_bind_into ] ( name ) ) and
198- arg = alias .getTypeRepr ( ) and
199- tp =
200- TAssociatedTypeTypeParameter ( resolved
201- .( TraitItemNode )
202- .getAssocItem ( pragma [ only_bind_into ] ( name ) ) )
203- )
204233 )
205234 }
206235}
0 commit comments