@@ -107,7 +107,7 @@ class SuccessorKind extends TSuccessorKind {
107107}
108108
109109pragma [ nomagic]
110- private ItemNode getAChildSuccessor ( ItemNode item , string name , SuccessorKind kind ) {
110+ private ItemNode getAChildSuccessor0 ( ItemNode item , string name , SuccessorKind kind ) {
111111 item = result .getImmediateParent ( ) and
112112 name = result .getName ( ) and
113113 // Associated items in `impl` and `trait` blocks are handled elsewhere
@@ -116,7 +116,7 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki
116116 if result instanceof TypeParam
117117 then kind .isInternal ( )
118118 else
119- if result .isPublic ( )
119+ if result .isPublic ( ) or item instanceof SourceFile
120120 then kind .isBoth ( )
121121 else kind .isInternal ( )
122122 or
@@ -130,6 +130,31 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki
130130 result = item
131131}
132132
133+ pragma [ nomagic]
134+ private ItemNode getAChildSuccessor ( ItemNode item , string name , SuccessorKind kind ) {
135+ result = getAChildSuccessor0 ( item , name , kind ) and
136+ // In valid Rust code, there cannot be multiple children with the same name and namespace,
137+ // but to safeguard against combinatorial explosions in invalid code, we always pick the
138+ // last child, except for modules, where we take the union.
139+ (
140+ not result instanceof NamedItemNode
141+ or
142+ result instanceof ModuleItemNode
143+ or
144+ exists ( Namespace ns |
145+ result =
146+ max ( NamedItemNode i , int startline , int startcolumn , int endline , int endcolumn |
147+ i .getLocation ( ) .hasLocationInfo ( _, startline , startcolumn , endline , endcolumn ) and
148+ i = getAChildSuccessor0 ( item , name , _) and
149+ ns = i .getNamespace ( ) and
150+ not i instanceof ModuleItemNode
151+ |
152+ i order by startline , startcolumn , endline , endcolumn
153+ )
154+ )
155+ )
156+ }
157+
133158private module UseOption = Option< Use > ;
134159
135160private class UseOption = UseOption:: Option ;
@@ -288,10 +313,6 @@ abstract class ItemNode extends Locatable {
288313 cached
289314 ItemNode getASuccessor ( string name , SuccessorKind kind , UseOption useOpt ) {
290315 Stages:: PathResolutionStage:: ref ( ) and
291- sourceFileEdge ( this , name , result ) and
292- kind .isBoth ( ) and
293- useOpt .isNone ( )
294- or
295316 result = getAChildSuccessor ( this , name , kind ) and
296317 useOpt .isNone ( )
297318 or
@@ -471,6 +492,8 @@ abstract class ItemNode extends Locatable {
471492 Location getLocation ( ) { result = super .getLocation ( ) }
472493}
473494
495+ abstract class NamedItemNode extends ItemNode { }
496+
474497abstract class TypeItemNode extends ItemNode { }
475498
476499/** A module or a source file. */
@@ -509,7 +532,7 @@ private class SourceFileItemNode extends ModuleLikeNode instanceof SourceFile {
509532 override string getCanonicalPath ( Crate c ) { none ( ) }
510533}
511534
512- class CrateItemNode extends ItemNode instanceof Crate {
535+ class CrateItemNode extends NamedItemNode instanceof Crate {
513536 /**
514537 * Gets the source file that defines this crate.
515538 */
@@ -565,15 +588,15 @@ class CrateItemNode extends ItemNode instanceof Crate {
565588 override string getCanonicalPath ( Crate c ) { c = this and result = Crate .super .getName ( ) }
566589}
567590
568- class ExternCrateItemNode extends ItemNode instanceof ExternCrate {
591+ class ExternCrateItemNode extends NamedItemNode instanceof ExternCrate {
569592 override string getName ( ) {
570593 result = super .getRename ( ) .getName ( ) .getText ( )
571594 or
572595 not super .hasRename ( ) and
573596 result = super .getIdentifier ( ) .getText ( )
574597 }
575598
576- override Namespace getNamespace ( ) { none ( ) }
599+ override Namespace getNamespace ( ) { result . isType ( ) }
577600
578601 override Visibility getVisibility ( ) { result = ExternCrate .super .getVisibility ( ) }
579602
@@ -587,7 +610,7 @@ class ExternCrateItemNode extends ItemNode instanceof ExternCrate {
587610}
588611
589612/** An item that can occur in a trait or an `impl` block. */
590- abstract private class AssocItemNode extends ItemNode instanceof AssocItem {
613+ abstract private class AssocItemNode extends NamedItemNode instanceof AssocItem {
591614 /** Holds if this associated item has an implementation. */
592615 abstract predicate hasImplementation ( ) ;
593616
@@ -626,7 +649,7 @@ private class ConstItemNode extends AssocItemNode instanceof Const {
626649 override TypeParam getTypeParam ( int i ) { none ( ) }
627650}
628651
629- private class TypeItemTypeItemNode extends TypeItemNode instanceof TypeItem {
652+ private class TypeItemTypeItemNode extends NamedItemNode , TypeItemNode instanceof TypeItem {
630653 override string getName ( ) { result = TypeItem .super .getName ( ) .getText ( ) }
631654
632655 override Namespace getNamespace ( ) { result .isType ( ) }
@@ -659,7 +682,7 @@ private class TypeItemTypeItemNode extends TypeItemNode instanceof TypeItem {
659682}
660683
661684/** An item that can be referenced with arguments. */
662- abstract class ParameterizableItemNode extends ItemNode {
685+ abstract class ParameterizableItemNode extends NamedItemNode {
663686 /** Gets the arity this item. */
664687 abstract int getArity ( ) ;
665688}
@@ -911,7 +934,7 @@ private class ImplTraitTypeReprItemNodeImpl extends ImplTraitTypeReprItemNode {
911934 ItemNode resolveABoundCand ( ) { result = resolvePathCand ( this .getABoundPath ( ) ) }
912935}
913936
914- private class ModuleItemNode extends ModuleLikeNode instanceof Module {
937+ private class ModuleItemNode extends NamedItemNode , ModuleLikeNode instanceof Module {
915938 override string getName ( ) { result = Module .super .getName ( ) .getText ( ) }
916939
917940 override Namespace getNamespace ( ) { result .isType ( ) }
@@ -929,7 +952,7 @@ private class ModuleItemNode extends ModuleLikeNode instanceof Module {
929952 (
930953 exists ( SourceFile f |
931954 fileImport ( this , f ) and
932- sourceFileEdge ( f , _, child )
955+ child = getAChildSuccessor ( f , _, _ )
933956 )
934957 or
935958 this = child .getImmediateParent ( )
@@ -1001,7 +1024,7 @@ private class StructItemNode extends TypeItemTypeItemNode, ParameterizableItemNo
10011024 }
10021025}
10031026
1004- final class TraitItemNode extends ImplOrTraitItemNode , TypeItemNode instanceof Trait {
1027+ final class TraitItemNode extends ImplOrTraitItemNode , NamedItemNode , TypeItemNode instanceof Trait {
10051028 pragma [ nomagic]
10061029 Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
10071030
@@ -1126,7 +1149,7 @@ private class BlockExprItemNode extends ItemNode instanceof BlockExpr {
11261149pragma [ nomagic]
11271150private Path getWherePredPath ( WherePred wp ) { result = wp .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
11281151
1129- final class TypeParamItemNode extends TypeItemNode instanceof TypeParam {
1152+ final class TypeParamItemNode extends NamedItemNode , TypeItemNode instanceof TypeParam {
11301153 /** Gets a where predicate for this type parameter, if any */
11311154 pragma [ nomagic]
11321155 private WherePred getAWherePred ( ) {
@@ -1214,7 +1237,7 @@ final private class TypeParamItemNodeImpl extends TypeParamItemNode instanceof T
12141237 ItemNode resolveABoundCand ( ) { result = resolvePathCand ( this .getABoundPathCand ( ) ) }
12151238}
12161239
1217- abstract private class MacroItemNode extends ItemNode {
1240+ abstract private class MacroItemNode extends NamedItemNode {
12181241 override Namespace getNamespace ( ) { result .isMacro ( ) }
12191242
12201243 override TypeParam getTypeParam ( int i ) { none ( ) }
@@ -1256,12 +1279,6 @@ private class MacroDefItemNode extends MacroItemNode instanceof MacroDef {
12561279 override Attr getAnAttr ( ) { result = MacroDef .super .getAnAttr ( ) }
12571280}
12581281
1259- /** Holds if `item` has the name `name` and is a top-level item inside `f`. */
1260- private predicate sourceFileEdge ( SourceFile f , string name , ItemNode item ) {
1261- item = f .( ItemNode ) .getADescendant ( ) and
1262- name = item .getName ( )
1263- }
1264-
12651282/** Holds if `f` is available as `mod name;` inside `folder`. */
12661283pragma [ nomagic]
12671284private predicate fileModule ( SourceFile f , string name , Folder folder ) {
0 commit comments