@@ -143,33 +143,73 @@ class NonAliasPathTypeMention extends PathTypeMention {
143143 )
144144 }
145145
146- private TypeMention getPositionalTypeArgument0 ( int i ) {
146+ /**
147+ * Gets the positional type argument at index `i` that occurs in this path, if
148+ * any.
149+ */
150+ private TypeMention getPathPositionalTypeArgument ( int i ) {
147151 result = this .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( i )
148152 or
149153 // `Option::<i32>::Some` is valid in addition to `Option::Some::<i32>`
150154 resolvePath ( this ) instanceof Variant and
151155 result = this .getQualifier ( ) .getSegment ( ) .getGenericArgList ( ) .getTypeArg ( i )
152156 }
153157
154- private TypeMention getPositionalTypeArgument ( int i ) {
155- result = this .getPositionalTypeArgument0 ( i )
158+ /**
159+ * Gets the type mention that instantiates the implicit `Self` type parameter
160+ * for this path, if it occurs in the position of a trait bound.
161+ */
162+ private TypeMention getSelfTraitBoundArg ( ) {
163+ exists ( ImplItemNode impl | this = impl .getTraitPath ( ) and result = impl .( Impl ) .getSelfTy ( ) )
156164 or
165+ exists ( Trait subTrait |
166+ this = subTrait .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) and
167+ result .( SelfTypeParameterMention ) .getTrait ( ) = subTrait
168+ )
169+ or
170+ exists ( TypeParamItemNode tp | this = tp .getABoundPath ( ) and result = tp )
171+ }
172+
173+ private Type getDefaultPositionalTypeArgument ( int i , TypePath path ) {
157174 // If a type argument is not given in the path, then we use the default for
158175 // the type parameter if one exists for the type.
159- not exists ( this .getPositionalTypeArgument0 ( i ) ) and
160- result = this .resolveRootType ( ) .getTypeParameterDefault ( i ) and
176+ not exists ( this .getPathPositionalTypeArgument ( i ) ) and
161177 // Defaults only apply to type mentions in type annotations
162- this = any ( PathTypeRepr ptp ) .getPath ( ) .getQualifier * ( )
178+ this = any ( PathTypeRepr ptp ) .getPath ( ) .getQualifier * ( ) and
179+ exists ( Type ty , TypePath prefix |
180+ ty = this .resolveRootType ( ) .getTypeParameterDefault ( i ) .resolveTypeAt ( prefix ) and
181+ if not ty = TSelfTypeParameter ( resolved )
182+ then result = ty and path = prefix
183+ else
184+ // When a default contains an implicit `Self` type parameter, it should
185+ // be substituted for the type that implements the trait.
186+ exists ( TypePath suffix |
187+ path = prefix .append ( suffix ) and
188+ result = this .getSelfTraitBoundArg ( ) .resolveTypeAt ( suffix )
189+ )
190+ )
163191 }
164192
165- /** Gets the type mention in this path for the type parameter `tp`, if any. */
166- pragma [ nomagic]
167- private TypeMention getTypeMentionForTypeParameter ( TypeParameter tp ) {
193+ private Type getPositionalTypeArgument ( int i , TypePath path ) {
194+ result = this .getPathPositionalTypeArgument ( i ) .resolveTypeAt ( path )
195+ or
196+ result = this .getDefaultPositionalTypeArgument ( i , path )
197+ }
198+
199+ /**
200+ * Gets the type for this path for the type parameter `tp` at `path`, when the
201+ * type parameter does not correspond directly to a type mention.
202+ */
203+ private Type getTypeForTypeParameterAt ( TypeParameter tp , TypePath path ) {
168204 exists ( int i |
169- result = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) ) and
205+ result = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) , path ) and
170206 tp = this .resolveRootType ( ) .getPositionalTypeParameter ( pragma [ only_bind_into ] ( i ) )
171207 )
172- or
208+ }
209+
210+ /** Gets the type mention in this path for the type parameter `tp`, if any. */
211+ pragma [ nomagic]
212+ private TypeMention getTypeMentionForTypeParameter ( TypeParameter tp ) {
173213 exists ( TypeAlias alias |
174214 result = this .getAnAssocTypeArgument ( alias ) and
175215 tp = TAssociatedTypeTypeParameter ( alias )
@@ -237,9 +277,17 @@ class NonAliasPathTypeMention extends PathTypeMention {
237277 typePath .isEmpty ( ) and
238278 result = this .resolveRootType ( )
239279 or
240- exists ( TypeParameter tp , TypePath suffix |
241- result = this .getTypeMentionForTypeParameter ( tp ) .resolveTypeAt ( suffix ) and
242- typePath = TypePath:: cons ( tp , suffix )
280+ exists ( TypeParameter tp , TypePath suffix | typePath = TypePath:: cons ( tp , suffix ) |
281+ result = this .getTypeForTypeParameterAt ( tp , suffix )
282+ or
283+ result = this .getTypeMentionForTypeParameter ( tp ) .resolveTypeAt ( suffix )
284+ )
285+ or
286+ // When the path refers to a trait, then the implicit `Self` type parameter
287+ // should be instantiated from the context.
288+ exists ( TypePath suffix |
289+ result = this .getSelfTraitBoundArg ( ) .resolveTypeAt ( suffix ) and
290+ typePath = TypePath:: cons ( TSelfTypeParameter ( resolved ) , suffix )
243291 )
244292 }
245293}
@@ -296,6 +344,11 @@ class TraitMention extends TypeMention instanceof TraitItemNode {
296344 typePath .isEmpty ( ) and
297345 result = TTrait ( this )
298346 or
347+ // The implicit `Self` type parameter occurs at the `Self` type parameter
348+ // position.
349+ typePath = TypePath:: singleton ( TSelfTypeParameter ( this ) ) and
350+ result = TSelfTypeParameter ( this )
351+ or
299352 exists ( TypeAlias alias |
300353 alias = super .getAnAssocItem ( ) and
301354 typePath = TypePath:: singleton ( result ) and
0 commit comments