@@ -208,6 +208,7 @@ abstract class ItemNode extends Locatable {
208208 crateDefEdge ( this , name , result , kind )
209209 or
210210 crateDependencyEdge ( this , name , result ) and
211+ not declaresDirectly ( this , TTypeNamespace ( ) , name ) and
211212 kind .isInternal ( )
212213 or
213214 externCrateEdge ( this , name , result ) and
@@ -311,6 +312,7 @@ abstract class ItemNode extends Locatable {
311312 }
312313
313314 /** Gets an _external_ successor named `name`, if any. */
315+ pragma [ nomagic]
314316 ItemNode getASuccessor ( string name ) {
315317 exists ( SuccessorKind kind |
316318 result = this .getASuccessor ( name , kind ) and
@@ -629,17 +631,17 @@ abstract class ImplOrTraitItemNode extends ItemNode {
629631
630632pragma [ nomagic]
631633private TypeParamItemNode resolveTypeParamPathTypeRepr ( PathTypeRepr ptr ) {
632- result = resolvePath ( ptr .getPath ( ) )
634+ result = resolvePathImpl ( ptr .getPath ( ) )
633635}
634636
635637class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
636638 Path getSelfPath ( ) { result = super .getSelfTy ( ) .( PathTypeRepr ) .getPath ( ) }
637639
638640 Path getTraitPath ( ) { result = super .getTrait ( ) .( PathTypeRepr ) .getPath ( ) }
639641
640- TypeItemNode resolveSelfTy ( ) { result = resolvePath ( this .getSelfPath ( ) ) }
642+ TypeItemNode resolveSelfTy ( ) { result = resolvePathImpl ( this .getSelfPath ( ) ) }
641643
642- TraitItemNode resolveTraitTy ( ) { result = resolvePath ( this .getTraitPath ( ) ) }
644+ TraitItemNode resolveTraitTy ( ) { result = resolvePathImpl ( this .getTraitPath ( ) ) }
643645
644646 override AssocItemNode getAnAssocItem ( ) { result = this .getADescendant ( ) }
645647
@@ -733,7 +735,7 @@ private class ImplTraitTypeReprItemNode extends TypeItemNode instanceof ImplTrai
733735 }
734736
735737 pragma [ nomagic]
736- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
738+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
737739
738740 override string getName ( ) { result = "(impl trait)" }
739741
@@ -830,7 +832,7 @@ class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof Trait {
830832 Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
831833
832834 pragma [ nomagic]
833- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
835+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
834836
835837 override AssocItemNode getAnAssocItem ( ) { result = this .getADescendant ( ) }
836838
@@ -882,7 +884,7 @@ class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof Trait {
882884
883885class TypeAliasItemNode extends TypeItemNode , AssocItemNode instanceof TypeAlias {
884886 pragma [ nomagic]
885- ItemNode resolveAlias ( ) { result = resolvePath ( super .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) ) }
887+ ItemNode resolveAlias ( ) { result = resolvePathImpl ( super .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) ) }
886888
887889 override string getName ( ) { result = TypeAlias .super .getName ( ) .getText ( ) }
888890
@@ -971,7 +973,7 @@ class TypeParamItemNode extends TypeItemNode instanceof TypeParam {
971973 Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
972974
973975 pragma [ nomagic]
974- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
976+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
975977
976978 /**
977979 * Holds if this type parameter has a trait bound. Examples:
@@ -1173,6 +1175,11 @@ private class BuiltinSourceFile extends SourceFileItemNode {
11731175pragma [ nomagic]
11741176private predicate crateDependencyEdge ( SourceFileItemNode file , string name , CrateItemNode dep ) {
11751177 exists ( CrateItemNode c | dep = c .( Crate ) .getDependency ( name ) | file = c .getASourceFile ( ) )
1178+ or
1179+ // All files _should_ belong to a crate, but for those where we cannot identify the crate,
1180+ // we give access to all crates as a fallback.
1181+ not file = any ( Crate c ) .getASourceFile ( ) and
1182+ name = dep .getName ( )
11761183}
11771184
11781185private predicate useTreeDeclares ( UseTree tree , string name ) {
@@ -1194,15 +1201,24 @@ private predicate useTreeDeclares(UseTree tree, string name) {
11941201
11951202/**
11961203 * Holds if `item` explicitly declares a sub item named `name` in the
1197- * namespace `ns`. This includes items declared by `use` statements,
1198- * except for glob imports.
1204+ * namespace `ns`. This excludes items declared by `use` statements.
11991205 */
12001206pragma [ nomagic]
1201- private predicate declares ( ItemNode item , Namespace ns , string name ) {
1207+ private predicate declaresDirectly ( ItemNode item , Namespace ns , string name ) {
12021208 exists ( ItemNode child , SuccessorKind kind | child = getAChildSuccessor ( item , name , kind ) |
12031209 child .getNamespace ( ) = ns and
12041210 kind .isInternalOrBoth ( )
12051211 )
1212+ }
1213+
1214+ /**
1215+ * Holds if `item` explicitly declares a sub item named `name` in the
1216+ * namespace `ns`. This includes items declared by `use` statements,
1217+ * except for glob imports.
1218+ */
1219+ pragma [ nomagic]
1220+ private predicate declares ( ItemNode item , Namespace ns , string name ) {
1221+ declaresDirectly ( item , ns , name )
12061222 or
12071223 exists ( ItemNode child |
12081224 child .getImmediateParent ( ) = item and
@@ -1326,9 +1342,9 @@ pragma[nomagic]
13261342private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
13271343
13281344pragma [ nomagic]
1329- private ItemNode resolvePath0 ( RelevantPath path , Namespace ns , SuccessorKind kind ) {
1345+ private ItemNode resolvePathImpl0 ( RelevantPath path , Namespace ns ) {
13301346 exists ( ItemNode res |
1331- res = unqualifiedPathLookup ( path , ns , kind ) and
1347+ res = unqualifiedPathLookup ( path , ns , _ ) and
13321348 if
13331349 not any ( RelevantPath parent ) .getQualifier ( ) = path and
13341350 isUnqualifiedSelfPath ( path ) and
@@ -1337,13 +1353,13 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns, SuccessorKind kin
13371353 else result = res
13381354 )
13391355 or
1340- exists ( ItemNode q , string name |
1341- q = resolvePathQualifier ( path , name ) and
1356+ exists ( ItemNode q , string name , SuccessorKind kind |
1357+ q = resolvePathImplQualifier ( path , name ) and
13421358 result = getASuccessor ( q , name , ns , kind ) and
13431359 kind .isExternalOrBoth ( )
13441360 )
13451361 or
1346- result = resolveUseTreeListItem ( _, _, path , kind ) and
1362+ result = resolveUseTreeListItem ( _, _, path , _ ) and
13471363 ns = result .getNamespace ( )
13481364}
13491365
@@ -1377,19 +1393,21 @@ private predicate pathUsesNamespace(Path p, Namespace n) {
13771393 )
13781394}
13791395
1380- /** Gets the item that `path` resolves to, if any. */
1381- cached
1382- ItemNode resolvePath ( RelevantPath path ) {
1396+ pragma [ nomagic]
1397+ private ItemNode resolvePathImpl ( RelevantPath path ) {
13831398 exists ( Namespace ns |
1384- result = resolvePath0 ( path , ns , _ ) and
1399+ result = resolvePathImpl0 ( path , ns ) and
13851400 if path = any ( ImplItemNode i ) .getSelfPath ( )
13861401 then
13871402 result instanceof TypeItemNode and
13881403 not result instanceof TraitItemNode
13891404 else
13901405 if path = any ( ImplItemNode i ) .getTraitPath ( )
13911406 then result instanceof TraitItemNode
1392- else any ( )
1407+ else
1408+ if path = any ( PathTypeRepr p ) .getPath ( )
1409+ then result instanceof TypeItemNode
1410+ else any ( )
13931411 |
13941412 pathUsesNamespace ( path , ns )
13951413 or
@@ -1399,11 +1417,36 @@ ItemNode resolvePath(RelevantPath path) {
13991417}
14001418
14011419pragma [ nomagic]
1402- private ItemNode resolvePathQualifier ( RelevantPath path , string name ) {
1403- result = resolvePath ( path .getQualifier ( ) ) and
1420+ private ItemNode resolvePathImplQualifier ( RelevantPath path , string name ) {
1421+ result = resolvePathImpl ( path .getQualifier ( ) ) and
14041422 name = path .getText ( )
14051423}
14061424
1425+ /** Gets the item that `path` resolves to, if any. */
1426+ cached
1427+ ItemNode resolvePath ( RelevantPath path ) {
1428+ result = resolvePathImpl ( path ) and
1429+ // if `path` is the qualifier of a resolvable parent, then we should
1430+ // resolve `path` to something consistent with what the parent resolves to
1431+ (
1432+ not path = any ( Path parent | exists ( resolvePathImpl ( parent ) ) ) .getQualifier ( )
1433+ or
1434+ exists ( ItemNode i , string name |
1435+ i = resolvePathParent ( path , name ) and
1436+ result .getASuccessor ( name ) = i
1437+ )
1438+ )
1439+ }
1440+
1441+ pragma [ nomagic]
1442+ private ItemNode resolvePathParent ( RelevantPath path , string name ) {
1443+ exists ( RelevantPath parent |
1444+ result = resolvePath ( parent ) and
1445+ path = parent .getQualifier ( ) and
1446+ name = parent .getText ( )
1447+ )
1448+ }
1449+
14071450private predicate isUseTreeSubPath ( UseTree tree , RelevantPath path ) {
14081451 path = tree .getPath ( )
14091452 or
@@ -1449,7 +1492,7 @@ private ItemNode resolveUseTreeListItemQualifier(
14491492pragma [ nomagic]
14501493private ItemNode resolveUseTreeListItem ( Use use , UseTree tree ) {
14511494 tree = use .getUseTree ( ) and
1452- result = resolvePath ( tree .getPath ( ) )
1495+ result = resolvePathImpl ( tree .getPath ( ) )
14531496 or
14541497 result = resolveUseTreeListItem ( use , tree , tree .getPath ( ) , _)
14551498}
@@ -1502,21 +1545,13 @@ private predicate externCrateEdge(ExternCrateItemNode ec, string name, CrateItem
15021545
15031546pragma [ nomagic]
15041547private predicate preludeItem ( string name , ItemNode i ) {
1505- exists (
1506- Crate stdOrCore , string stdOrCoreName , ModuleLikeNode mod , ModuleItemNode prelude ,
1507- ModuleItemNode rust
1508- |
1509- stdOrCore .getName ( ) = stdOrCoreName and
1510- stdOrCoreName = [ "std" , "core" ] and
1548+ exists ( Crate stdOrCore , ModuleLikeNode mod , ModuleItemNode prelude , ModuleItemNode rust |
1549+ stdOrCore .getName ( ) = [ "std" , "core" ] and
15111550 mod = stdOrCore .getSourceFile ( ) and
15121551 prelude = mod .getASuccessor ( "prelude" ) and
1513- rust = prelude .getASuccessor ( [ "rust_2015" , "rust_2018" , "rust_2021" , "rust_2024" ] )
1514- |
1552+ rust = prelude .getASuccessor ( [ "rust_2015" , "rust_2018" , "rust_2021" , "rust_2024" ] ) and
15151553 i = rust .getASuccessor ( name ) and
15161554 not name = [ "super" , "self" ]
1517- or
1518- name = stdOrCoreName and
1519- i = stdOrCore
15201555 )
15211556}
15221557
@@ -1533,7 +1568,7 @@ private predicate preludeItem(string name, ItemNode i) {
15331568pragma [ nomagic]
15341569private predicate preludeEdge ( SourceFile f , string name , ItemNode i ) {
15351570 preludeItem ( name , i ) and
1536- not declares ( f , _ , name )
1571+ not declares ( f , i . getNamespace ( ) , name )
15371572}
15381573
15391574pragma [ nomagic]
0 commit comments