@@ -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,41 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki
130130 result = item
131131}
132132
133+ pragma [ nomagic]
134+ private NamedItemNode getANamedNonModuleChildSuccessor (
135+ ItemNode item , string name , Namespace ns , int startline , int startcolumn , int endline ,
136+ int endcolumn
137+ ) {
138+ result .getLocation ( ) .hasLocationInfo ( _, startline , startcolumn , endline , endcolumn ) and
139+ result = getAChildSuccessor0 ( item , name , _) and
140+ ns = result .getNamespace ( ) and
141+ not result instanceof ModuleItemNode
142+ }
143+
144+ pragma [ nomagic]
145+ private ItemNode getAChildSuccessor ( ItemNode item , string name , SuccessorKind kind ) {
146+ result = getAChildSuccessor0 ( item , name , kind ) and
147+ // In valid Rust code, there cannot be multiple children with the same name and namespace,
148+ // but to safeguard against combinatorial explosions in invalid code, we always pick the
149+ // last child, except for modules, where we take the union.
150+ (
151+ not result instanceof NamedItemNode
152+ or
153+ result instanceof ModuleItemNode
154+ or
155+ exists ( Namespace ns |
156+ result =
157+ max ( NamedItemNode i , int startline , int startcolumn , int endline , int endcolumn |
158+ i =
159+ getANamedNonModuleChildSuccessor ( item , name , ns , startline , startcolumn , endline ,
160+ endcolumn )
161+ |
162+ i order by startline , startcolumn , endline , endcolumn
163+ )
164+ )
165+ )
166+ }
167+
133168private module UseOption = Option< Use > ;
134169
135170private class UseOption = UseOption:: Option ;
@@ -288,10 +323,6 @@ abstract class ItemNode extends Locatable {
288323 cached
289324 ItemNode getASuccessor ( string name , SuccessorKind kind , UseOption useOpt ) {
290325 Stages:: PathResolutionStage:: ref ( ) and
291- sourceFileEdge ( this , name , result ) and
292- kind .isBoth ( ) and
293- useOpt .isNone ( )
294- or
295326 result = getAChildSuccessor ( this , name , kind ) and
296327 useOpt .isNone ( )
297328 or
@@ -471,6 +502,8 @@ abstract class ItemNode extends Locatable {
471502 Location getLocation ( ) { result = super .getLocation ( ) }
472503}
473504
505+ abstract class NamedItemNode extends ItemNode { }
506+
474507abstract class TypeItemNode extends ItemNode { }
475508
476509/** A module or a source file. */
@@ -509,7 +542,7 @@ private class SourceFileItemNode extends ModuleLikeNode instanceof SourceFile {
509542 override string getCanonicalPath ( Crate c ) { none ( ) }
510543}
511544
512- class CrateItemNode extends ItemNode instanceof Crate {
545+ class CrateItemNode extends NamedItemNode instanceof Crate {
513546 /**
514547 * Gets the source file that defines this crate.
515548 */
@@ -565,15 +598,15 @@ class CrateItemNode extends ItemNode instanceof Crate {
565598 override string getCanonicalPath ( Crate c ) { c = this and result = Crate .super .getName ( ) }
566599}
567600
568- class ExternCrateItemNode extends ItemNode instanceof ExternCrate {
601+ class ExternCrateItemNode extends NamedItemNode instanceof ExternCrate {
569602 override string getName ( ) {
570603 result = super .getRename ( ) .getName ( ) .getText ( )
571604 or
572605 not super .hasRename ( ) and
573606 result = super .getIdentifier ( ) .getText ( )
574607 }
575608
576- override Namespace getNamespace ( ) { none ( ) }
609+ override Namespace getNamespace ( ) { result . isType ( ) }
577610
578611 override Visibility getVisibility ( ) { result = ExternCrate .super .getVisibility ( ) }
579612
@@ -587,7 +620,7 @@ class ExternCrateItemNode extends ItemNode instanceof ExternCrate {
587620}
588621
589622/** An item that can occur in a trait or an `impl` block. */
590- abstract private class AssocItemNode extends ItemNode instanceof AssocItem {
623+ abstract private class AssocItemNode extends NamedItemNode instanceof AssocItem {
591624 /** Holds if this associated item has an implementation. */
592625 abstract predicate hasImplementation ( ) ;
593626
@@ -626,7 +659,7 @@ private class ConstItemNode extends AssocItemNode instanceof Const {
626659 override TypeParam getTypeParam ( int i ) { none ( ) }
627660}
628661
629- private class TypeItemTypeItemNode extends TypeItemNode instanceof TypeItem {
662+ private class TypeItemTypeItemNode extends NamedItemNode , TypeItemNode instanceof TypeItem {
630663 override string getName ( ) { result = TypeItem .super .getName ( ) .getText ( ) }
631664
632665 override Namespace getNamespace ( ) { result .isType ( ) }
@@ -659,7 +692,7 @@ private class TypeItemTypeItemNode extends TypeItemNode instanceof TypeItem {
659692}
660693
661694/** An item that can be referenced with arguments. */
662- abstract class ParameterizableItemNode extends ItemNode {
695+ abstract class ParameterizableItemNode extends NamedItemNode {
663696 /** Gets the arity this item. */
664697 abstract int getArity ( ) ;
665698}
@@ -911,7 +944,7 @@ private class ImplTraitTypeReprItemNodeImpl extends ImplTraitTypeReprItemNode {
911944 ItemNode resolveABoundCand ( ) { result = resolvePathCand ( this .getABoundPath ( ) ) }
912945}
913946
914- private class ModuleItemNode extends ModuleLikeNode instanceof Module {
947+ private class ModuleItemNode extends NamedItemNode , ModuleLikeNode instanceof Module {
915948 override string getName ( ) { result = Module .super .getName ( ) .getText ( ) }
916949
917950 override Namespace getNamespace ( ) { result .isType ( ) }
@@ -929,7 +962,7 @@ private class ModuleItemNode extends ModuleLikeNode instanceof Module {
929962 (
930963 exists ( SourceFile f |
931964 fileImport ( this , f ) and
932- sourceFileEdge ( f , _, child )
965+ child = getAChildSuccessor ( f , _, _ )
933966 )
934967 or
935968 this = child .getImmediateParent ( )
@@ -1001,7 +1034,7 @@ private class StructItemNode extends TypeItemTypeItemNode, ParameterizableItemNo
10011034 }
10021035}
10031036
1004- final class TraitItemNode extends ImplOrTraitItemNode , TypeItemNode instanceof Trait {
1037+ final class TraitItemNode extends ImplOrTraitItemNode , NamedItemNode , TypeItemNode instanceof Trait {
10051038 pragma [ nomagic]
10061039 Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
10071040
@@ -1126,7 +1159,7 @@ private class BlockExprItemNode extends ItemNode instanceof BlockExpr {
11261159pragma [ nomagic]
11271160private Path getWherePredPath ( WherePred wp ) { result = wp .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
11281161
1129- final class TypeParamItemNode extends TypeItemNode instanceof TypeParam {
1162+ final class TypeParamItemNode extends NamedItemNode , TypeItemNode instanceof TypeParam {
11301163 /** Gets a where predicate for this type parameter, if any */
11311164 pragma [ nomagic]
11321165 private WherePred getAWherePred ( ) {
@@ -1214,7 +1247,7 @@ final private class TypeParamItemNodeImpl extends TypeParamItemNode instanceof T
12141247 ItemNode resolveABoundCand ( ) { result = resolvePathCand ( this .getABoundPathCand ( ) ) }
12151248}
12161249
1217- abstract private class MacroItemNode extends ItemNode {
1250+ abstract private class MacroItemNode extends NamedItemNode {
12181251 override Namespace getNamespace ( ) { result .isMacro ( ) }
12191252
12201253 override TypeParam getTypeParam ( int i ) { none ( ) }
@@ -1256,12 +1289,6 @@ private class MacroDefItemNode extends MacroItemNode instanceof MacroDef {
12561289 override Attr getAnAttr ( ) { result = MacroDef .super .getAnAttr ( ) }
12571290}
12581291
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-
12651292/** Holds if `f` is available as `mod name;` inside `folder`. */
12661293pragma [ nomagic]
12671294private predicate fileModule ( SourceFile f , string name , Folder folder ) {
0 commit comments