@@ -264,6 +264,9 @@ abstract class ItemNode extends Locatable {
264264 pragma [ nomagic]
265265 ItemNode getImmediateParent ( ) { this = result .getADescendant ( ) }
266266
267+ /** Gets a child item of this item, if any. */
268+ ItemNode getAChild ( ) { this = result .getImmediateParent ( ) }
269+
267270 /** Gets the immediately enclosing module (or source file) of this item. */
268271 pragma [ nomagic]
269272 ModuleLikeNode getImmediateParentModule ( ) {
@@ -339,10 +342,13 @@ abstract class ItemNode extends Locatable {
339342 typeImplEdge ( this , _, name , kind , result , useOpt )
340343 or
341344 // trait items with default implementations made available in an implementation
342- exists ( ImplItemNodeImpl impl , ItemNode trait |
345+ exists ( ImplItemNodeImpl impl , TraitItemNode trait |
343346 this = impl and
344347 trait = impl .resolveTraitTyCand ( ) and
345348 result = trait .getASuccessor ( name , kind , useOpt ) and
349+ // do not inherit default implementations from super traits; those are inherited by
350+ // their `impl` blocks
351+ result = trait .getAssocItem ( name ) and
346352 result .( AssocItemNode ) .hasImplementation ( ) and
347353 kind .isExternalOrBoth ( ) and
348354 not impl .hasAssocItem ( name )
@@ -402,8 +408,14 @@ abstract class ItemNode extends Locatable {
402408 this instanceof SourceFile and
403409 builtin ( name , result )
404410 or
405- name = "Self" and
406- this = result .( ImplOrTraitItemNode ) .getAnItemInSelfScope ( )
411+ exists ( ImplOrTraitItemNode i |
412+ name = "Self" and
413+ this = i .getAnItemInSelfScope ( )
414+ |
415+ result = i .( Trait )
416+ or
417+ result = i .( ImplItemNodeImpl ) .resolveSelfTyCand ( )
418+ )
407419 or
408420 name = "crate" and
409421 this = result .( CrateItemNode ) .getASourceFile ( )
@@ -734,7 +746,7 @@ abstract class ImplOrTraitItemNode extends ItemNode {
734746 Path getASelfPath ( ) {
735747 Stages:: PathResolutionStage:: ref ( ) and
736748 isUnqualifiedSelfPath ( result ) and
737- this = unqualifiedPathLookup ( result , _ , _ )
749+ result = this . getAnItemInSelfScope ( ) . getADescendant ( )
738750 }
739751
740752 /** Gets an associated item belonging to this trait or `impl` block. */
@@ -960,7 +972,7 @@ private class ImplItemNodeImpl extends ImplItemNode {
960972 result = this .resolveSelfTyBuiltin ( )
961973 }
962974
963- TraitItemNode resolveTraitTyCand ( ) { result = resolvePathCand ( this .getTraitPath ( ) ) }
975+ TraitItemNodeImpl resolveTraitTyCand ( ) { result = resolvePathCand ( this .getTraitPath ( ) ) }
964976}
965977
966978private class StructItemNode extends TypeItemNode , ParameterizableItemNode instanceof Struct {
@@ -1813,15 +1825,7 @@ private module DollarCrateResolution {
18131825
18141826pragma [ nomagic]
18151827private ItemNode resolvePathCand0 ( PathExt path , Namespace ns ) {
1816- exists ( ItemNode res |
1817- res = unqualifiedPathLookup ( path , ns , _) and
1818- if
1819- not any ( PathExt parent ) .getQualifier ( ) = path and
1820- isUnqualifiedSelfPath ( path ) and
1821- res instanceof ImplItemNode
1822- then result = res .( ImplItemNodeImpl ) .resolveSelfTyCand ( )
1823- else result = res
1824- )
1828+ result = unqualifiedPathLookup ( path , ns , _)
18251829 or
18261830 DollarCrateResolution:: resolveDollarCrate ( path , result ) and
18271831 ns = result .getNamespace ( )
@@ -1883,12 +1887,35 @@ private predicate checkQualifiedVisibility(
18831887 not i instanceof TypeParam
18841888}
18851889
1890+ pragma [ nomagic]
1891+ private predicate isImplSelfQualifiedPath (
1892+ ImplItemNode impl , PathExt qualifier , PathExt path , string name
1893+ ) {
1894+ qualifier = impl .getASelfPath ( ) and
1895+ qualifier = path .getQualifier ( ) and
1896+ name = path .getText ( )
1897+ }
1898+
1899+ private ItemNode resolveImplSelfQualified ( PathExt qualifier , PathExt path , Namespace ns ) {
1900+ exists ( ImplItemNode impl , string name |
1901+ isImplSelfQualifiedPath ( impl , qualifier , path , name ) and
1902+ result = impl .getAssocItem ( name ) and
1903+ ns = result .getNamespace ( )
1904+ )
1905+ }
1906+
18861907/**
18871908 * Gets the item that `path` resolves to in `ns` when `qualifier` is the
18881909 * qualifier of `path` and `qualifier` resolves to `q`, if any.
18891910 */
18901911pragma [ nomagic]
18911912private ItemNode resolvePathCandQualified ( PathExt qualifier , ItemNode q , PathExt path , Namespace ns ) {
1913+ // Special case for `Self::Assoc`; this always refers to the associated
1914+ // item in the enclosing `impl` block, if available.
1915+ q = resolvePathCandQualifier ( qualifier , path , _) and
1916+ result = resolveImplSelfQualified ( qualifier , path , ns )
1917+ or
1918+ not exists ( resolveImplSelfQualified ( qualifier , path , ns ) ) and
18921919 exists ( string name , SuccessorKind kind , UseOption useOpt |
18931920 q = resolvePathCandQualifier ( qualifier , path , name ) and
18941921 result = getASuccessor ( q , name , ns , kind , useOpt ) and
0 commit comments