@@ -151,25 +151,61 @@ 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
165- /** Gets the type mention in this path for the type parameter `tp`, if any. */
166- pragma [ nomagic]
167- private TypeMention getTypeMentionForTypeParameter ( TypeParameter tp ) {
195+ /**
196+ * Gets the type for this path for the type parameter `tp` at `path`, when the
197+ * type parameter does not correspond directly to a type mention.
198+ */
199+ private Type getTypeForTypeParameterAt ( TypeParameter tp , TypePath path ) {
168200 exists ( int i |
169- result = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) ) and
201+ result = this .getPositionalTypeArgument ( pragma [ only_bind_into ] ( i ) , path ) and
170202 tp = this .resolveRootType ( ) .getPositionalTypeParameter ( pragma [ only_bind_into ] ( i ) )
171203 )
172- or
204+ }
205+
206+ /** Gets the type mention in this path for the type parameter `tp`, if any. */
207+ pragma [ nomagic]
208+ private TypeMention getTypeMentionForTypeParameter ( TypeParameter tp ) {
173209 exists ( TypeAlias alias |
174210 result = this .getAnAssocTypeArgument ( alias ) and
175211 tp = TAssociatedTypeTypeParameter ( alias )
@@ -237,9 +273,17 @@ class NonAliasPathTypeMention extends PathTypeMention {
237273 typePath .isEmpty ( ) and
238274 result = this .resolveRootType ( )
239275 or
240- exists ( TypeParameter tp , TypePath suffix |
241- result = this .getTypeMentionForTypeParameter ( tp ) .resolveTypeAt ( suffix ) and
242- typePath = TypePath:: cons ( tp , suffix )
276+ exists ( TypeParameter tp , TypePath suffix | typePath = TypePath:: cons ( tp , suffix ) |
277+ result = this .getTypeForTypeParameterAt ( tp , suffix )
278+ or
279+ result = this .getTypeMentionForTypeParameter ( tp ) .resolveTypeAt ( suffix )
280+ )
281+ or
282+ // When the path refers to a trait, then the implicit `Self` type parameter
283+ // should be instantiated from the context.
284+ exists ( TypePath suffix |
285+ result = this .getSelfTypeParameter ( ) .resolveTypeAt ( suffix ) and
286+ typePath = TypePath:: cons ( TSelfTypeParameter ( resolved ) , suffix )
243287 )
244288 }
245289}
@@ -296,6 +340,11 @@ class TraitMention extends TypeMention instanceof TraitItemNode {
296340 typePath .isEmpty ( ) and
297341 result = TTrait ( this )
298342 or
343+ // The implicit `Self` type parameter occurs at the `Self` type parameter
344+ // position.
345+ typePath = TypePath:: singleton ( TSelfTypeParameter ( this ) ) and
346+ result = TSelfTypeParameter ( this )
347+ or
299348 exists ( TypeAlias alias |
300349 alias = super .getAnAssocItem ( ) and
301350 typePath = TypePath:: singleton ( result ) and
0 commit comments