@@ -151,64 +151,96 @@ class NonAliasPathTypeMention extends PathTypeMention {
151151 result = this .getQualifier ( ) .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( i )
152152 }
153153
154- private TypeMention getPositionalTypeArgument ( int i ) {
155- result = this .getPositionalTypeArgument0 ( i )
154+ /**
155+ * Gets the type mention that instantiates the implicit `Self` type parameter
156+ * for this path, if it occurs in the position of a trait bound.
157+ */
158+ private TypeMention getSelfTypeParameter ( ) {
159+ exists ( ImplItemNode impl | this = impl .getTraitPath ( ) and result = impl .( Impl ) .getSelfTy ( ) )
160+ or
161+ exists ( Trait subTrait |
162+ this = subTrait .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) and
163+ result .( SelfTypeParameterMention ) .getTrait ( ) = subTrait
164+ )
165+ or
166+ exists ( TypeParamItemNode tp | this = tp .getABoundPath ( ) and result = tp )
167+ }
168+
169+ private Type getPositionalTypeArgument ( int i , TypePath path ) {
170+ result = this .getPositionalTypeArgument0 ( i ) .resolveTypeAt ( path )
156171 or
172+ result = this .getDefaultPositionalTypeArgument ( i , path )
173+ }
174+
175+ private Type getDefaultPositionalTypeArgument ( int i , TypePath path ) {
157176 // If a type argument is not given in the path, then we use the default for
158177 // the type parameter if one exists for the type.
159178 not exists ( this .getPositionalTypeArgument0 ( i ) ) and
160- result = this .resolveRootType ( ) .getTypeParameterDefault ( i ) and
161179 // Defaults only apply to type mentions in type annotations
162- this = any ( PathTypeRepr ptp ) .getPath ( ) .getQualifier * ( )
180+ this = any ( PathTypeRepr ptp ) .getPath ( ) .getQualifier * ( ) and
181+ exists ( Type ty , TypePath prefix |
182+ ty = this .resolveRootType ( ) .getTypeParameterDefault ( i ) .resolveTypeAt ( prefix ) and
183+ if not ty = TSelfTypeParameter ( resolved )
184+ then result = ty and path = prefix
185+ else
186+ // When a default contains an implicit `Self` type parameter, it should
187+ // be substituted for the type that implements the trait.
188+ exists ( TypePath suffix |
189+ path = prefix .append ( suffix ) and
190+ result = this .getSelfTypeParameter ( ) .resolveTypeAt ( suffix )
191+ )
192+ )
163193 }
164194
165195 /** Gets the type mention in this path for the type parameter `tp`, if any. */
166196 pragma [ nomagic]
167- private TypeMention getTypeMentionForTypeParameter ( TypeParameter tp ) {
197+ private Type getTypeForTypeParameterAt ( TypeParameter tp , TypePath path ) {
168198 exists ( int i |
169- result = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) ) and
199+ result = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) , path ) and
170200 tp = this .resolveRootType ( ) .getPositionalTypeParameter ( pragma [ only_bind_into ] ( i ) )
171201 )
172202 or
173- exists ( TypeAlias alias |
174- result = this .getAnAssocTypeArgument ( alias ) and
175- tp = TAssociatedTypeTypeParameter ( alias )
176- )
177- or
178- // If `path` is the trait of an `impl` block then any associated types
179- // defined in the `impl` block are type arguments to the trait.
180- //
181- // For instance, for a trait implementation like this
182- // ```rust
183- // impl MyTrait for MyType {
184- // ^^^^^^^ path
185- // type AssociatedType = i64
186- // ^^^ result
187- // // ...
188- // }
189- // ```
190- // the rhs. of the type alias is a type argument to the trait.
191- exists ( ImplItemNode impl , AssociatedTypeTypeParameter param , TypeAlias alias , string name |
192- this = impl .getTraitPath ( ) and
193- param .getTrait ( ) = resolved and
194- name = param .getTypeAlias ( ) .getName ( ) .getText ( ) and
195- alias = impl .getASuccessor ( pragma [ only_bind_into ] ( name ) ) and
196- result = alias .getTypeRepr ( ) and
197- tp =
198- TAssociatedTypeTypeParameter ( resolved
199- .( TraitItemNode )
200- .getAssocItem ( pragma [ only_bind_into ] ( name ) ) )
201- )
202- or
203- // Handle the special syntactic sugar for function traits. For now we only
204- // support `FnOnce` as we can't support the "inherited" associated types of
205- // `Fn` and `FnMut` yet.
206- exists ( FnOnceTrait t | t = resolved |
207- tp = TTypeParamTypeParameter ( t .getTypeParam ( ) ) and
208- result = this .getSegment ( ) .getParenthesizedArgList ( )
203+ exists ( TypeMention tm | result = tm .resolveTypeAt ( path ) |
204+ exists ( TypeAlias alias |
205+ tm = this .getAnAssocTypeArgument ( alias ) and
206+ tp = TAssociatedTypeTypeParameter ( alias )
207+ )
208+ or
209+ // If `path` is the trait of an `impl` block then any associated types
210+ // defined in the `impl` block are type arguments to the trait.
211+ //
212+ // For instance, for a trait implementation like this
213+ // ```rust
214+ // impl MyTrait for MyType {
215+ // ^^^^^^^ path
216+ // type AssociatedType = i64
217+ // ^^^ tm
218+ // // ...
219+ // }
220+ // ```
221+ // the rhs. of the type alias is a type argument to the trait.
222+ exists ( ImplItemNode impl , AssociatedTypeTypeParameter param , TypeAlias alias , string name |
223+ this = impl .getTraitPath ( ) and
224+ param .getTrait ( ) = resolved and
225+ name = param .getTypeAlias ( ) .getName ( ) .getText ( ) and
226+ alias = impl .getASuccessor ( pragma [ only_bind_into ] ( name ) ) and
227+ tm = alias .getTypeRepr ( ) and
228+ tp =
229+ TAssociatedTypeTypeParameter ( resolved
230+ .( TraitItemNode )
231+ .getAssocItem ( pragma [ only_bind_into ] ( name ) ) )
232+ )
209233 or
210- tp = TAssociatedTypeTypeParameter ( t .getOutputType ( ) ) and
211- result = this .getSegment ( ) .getRetType ( ) .getTypeRepr ( )
234+ // Handle the special syntactic sugar for function traits. For now we only
235+ // support `FnOnce` as we can't support the "inherited" associated types of
236+ // `Fn` and `FnMut` yet.
237+ exists ( FnOnceTrait t | t = resolved |
238+ tp = TTypeParamTypeParameter ( t .getTypeParam ( ) ) and
239+ tm = this .getSegment ( ) .getParenthesizedArgList ( )
240+ or
241+ tp = TAssociatedTypeTypeParameter ( t .getOutputType ( ) ) and
242+ tm = this .getSegment ( ) .getRetType ( ) .getTypeRepr ( )
243+ )
212244 )
213245 }
214246
@@ -238,9 +270,16 @@ class NonAliasPathTypeMention extends PathTypeMention {
238270 result = this .resolveRootType ( )
239271 or
240272 exists ( TypeParameter tp , TypePath suffix |
241- result = this .getTypeMentionForTypeParameter ( tp ) . resolveTypeAt ( suffix ) and
273+ result = this .getTypeForTypeParameterAt ( tp , suffix ) and
242274 typePath = TypePath:: cons ( tp , suffix )
243275 )
276+ or
277+ // When the path refers to a trait, then the implicit `Self` type parameter
278+ // should be instantiated from the context.
279+ exists ( TypePath suffix |
280+ result = this .getSelfTypeParameter ( ) .resolveTypeAt ( suffix ) and
281+ typePath = TypePath:: cons ( TSelfTypeParameter ( resolved ) , suffix )
282+ )
244283 }
245284}
246285
@@ -296,6 +335,11 @@ class TraitMention extends TypeMention instanceof TraitItemNode {
296335 typePath .isEmpty ( ) and
297336 result = TTrait ( this )
298337 or
338+ // The implicit `Self` type parameter occurs at the `Self` type parameter
339+ // position.
340+ typePath = TypePath:: singleton ( TSelfTypeParameter ( this ) ) and
341+ result = TSelfTypeParameter ( this )
342+ or
299343 exists ( TypeAlias alias |
300344 alias = super .getAnAssocItem ( ) and
301345 typePath = TypePath:: singleton ( result ) and
0 commit comments