@@ -188,6 +188,7 @@ abstract class ItemNode extends Locatable {
188188 crateDefEdge ( this , name , result , kind )
189189 or
190190 crateDependencyEdge ( this , name , result ) and
191+ not declaresDirectly ( this , TTypeNamespace ( ) , name ) and
191192 kind .isInternal ( )
192193 or
193194 externCrateEdge ( this , name , result ) and
@@ -291,6 +292,7 @@ abstract class ItemNode extends Locatable {
291292 }
292293
293294 /** Gets an _external_ successor named `name`, if any. */
295+ pragma [ nomagic]
294296 ItemNode getASuccessor ( string name ) {
295297 exists ( SuccessorKind kind |
296298 result = this .getASuccessor ( name , kind ) and
@@ -609,17 +611,17 @@ abstract class ImplOrTraitItemNode extends ItemNode {
609611
610612pragma [ nomagic]
611613private TypeParamItemNode resolveTypeParamPathTypeRepr ( PathTypeRepr ptr ) {
612- result = resolvePath ( ptr .getPath ( ) )
614+ result = resolvePathImpl ( ptr .getPath ( ) )
613615}
614616
615617class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
616618 Path getSelfPath ( ) { result = super .getSelfTy ( ) .( PathTypeRepr ) .getPath ( ) }
617619
618620 Path getTraitPath ( ) { result = super .getTrait ( ) .( PathTypeRepr ) .getPath ( ) }
619621
620- TypeItemNode resolveSelfTy ( ) { result = resolvePath ( this .getSelfPath ( ) ) }
622+ TypeItemNode resolveSelfTy ( ) { result = resolvePathImpl ( this .getSelfPath ( ) ) }
621623
622- TraitItemNode resolveTraitTy ( ) { result = resolvePath ( this .getTraitPath ( ) ) }
624+ TraitItemNode resolveTraitTy ( ) { result = resolvePathImpl ( this .getTraitPath ( ) ) }
623625
624626 override AssocItemNode getAnAssocItem ( ) { result = this .getADescendant ( ) }
625627
@@ -713,7 +715,7 @@ private class ImplTraitTypeReprItemNode extends TypeItemNode instanceof ImplTrai
713715 }
714716
715717 pragma [ nomagic]
716- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
718+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
717719
718720 override string getName ( ) { result = "(impl trait)" }
719721
@@ -810,7 +812,7 @@ class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof Trait {
810812 Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
811813
812814 pragma [ nomagic]
813- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
815+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
814816
815817 override AssocItemNode getAnAssocItem ( ) { result = this .getADescendant ( ) }
816818
@@ -862,7 +864,7 @@ class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof Trait {
862864
863865class TypeAliasItemNode extends TypeItemNode , AssocItemNode instanceof TypeAlias {
864866 pragma [ nomagic]
865- ItemNode resolveAlias ( ) { result = resolvePath ( super .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) ) }
867+ ItemNode resolveAlias ( ) { result = resolvePathImpl ( super .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) ) }
866868
867869 override string getName ( ) { result = TypeAlias .super .getName ( ) .getText ( ) }
868870
@@ -951,7 +953,7 @@ class TypeParamItemNode extends TypeItemNode instanceof TypeParam {
951953 Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
952954
953955 pragma [ nomagic]
954- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
956+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
955957
956958 /**
957959 * Holds if this type parameter has a trait bound. Examples:
@@ -1153,6 +1155,11 @@ private class BuiltinSourceFile extends SourceFileItemNode {
11531155pragma [ nomagic]
11541156private predicate crateDependencyEdge ( SourceFileItemNode file , string name , CrateItemNode dep ) {
11551157 exists ( CrateItemNode c | dep = c .( Crate ) .getDependency ( name ) | file = c .getASourceFile ( ) )
1158+ or
1159+ // All files _should_ belong to a crate, but for those where we cannot identify the crate,
1160+ // we give access to all crates as a fallback.
1161+ not file = any ( Crate c ) .getASourceFile ( ) and
1162+ name = dep .getName ( )
11561163}
11571164
11581165private predicate useTreeDeclares ( UseTree tree , string name ) {
@@ -1174,15 +1181,24 @@ private predicate useTreeDeclares(UseTree tree, string name) {
11741181
11751182/**
11761183 * Holds if `item` explicitly declares a sub item named `name` in the
1177- * namespace `ns`. This includes items declared by `use` statements,
1178- * except for glob imports.
1184+ * namespace `ns`. This excludes items declared by `use` statements.
11791185 */
11801186pragma [ nomagic]
1181- private predicate declares ( ItemNode item , Namespace ns , string name ) {
1187+ private predicate declaresDirectly ( ItemNode item , Namespace ns , string name ) {
11821188 exists ( ItemNode child , SuccessorKind kind | child = getAChildSuccessor ( item , name , kind ) |
11831189 child .getNamespace ( ) = ns and
11841190 kind .isInternalOrBoth ( )
11851191 )
1192+ }
1193+
1194+ /**
1195+ * Holds if `item` explicitly declares a sub item named `name` in the
1196+ * namespace `ns`. This includes items declared by `use` statements,
1197+ * except for glob imports.
1198+ */
1199+ pragma [ nomagic]
1200+ private predicate declares ( ItemNode item , Namespace ns , string name ) {
1201+ declaresDirectly ( item , ns , name )
11861202 or
11871203 exists ( ItemNode child |
11881204 child .getImmediateParent ( ) = item and
@@ -1306,9 +1322,9 @@ pragma[nomagic]
13061322private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
13071323
13081324pragma [ nomagic]
1309- private ItemNode resolvePath0 ( RelevantPath path , Namespace ns , SuccessorKind kind ) {
1325+ private ItemNode resolvePathImpl0 ( RelevantPath path , Namespace ns ) {
13101326 exists ( ItemNode res |
1311- res = unqualifiedPathLookup ( path , ns , kind ) and
1327+ res = unqualifiedPathLookup ( path , ns , _ ) and
13121328 if
13131329 not any ( RelevantPath parent ) .getQualifier ( ) = path and
13141330 isUnqualifiedSelfPath ( path ) and
@@ -1317,13 +1333,13 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns, SuccessorKind kin
13171333 else result = res
13181334 )
13191335 or
1320- exists ( ItemNode q , string name |
1321- q = resolvePathQualifier ( path , name ) and
1336+ exists ( ItemNode q , string name , SuccessorKind kind |
1337+ q = resolvePathImplQualifier ( path , name ) and
13221338 result = getASuccessor ( q , name , ns , kind ) and
13231339 kind .isExternalOrBoth ( )
13241340 )
13251341 or
1326- result = resolveUseTreeListItem ( _, _, path , kind ) and
1342+ result = resolveUseTreeListItem ( _, _, path , _ ) and
13271343 ns = result .getNamespace ( )
13281344}
13291345
@@ -1357,19 +1373,21 @@ private predicate pathUsesNamespace(Path p, Namespace n) {
13571373 )
13581374}
13591375
1360- /** Gets the item that `path` resolves to, if any. */
1361- cached
1362- ItemNode resolvePath ( RelevantPath path ) {
1376+ pragma [ nomagic]
1377+ private ItemNode resolvePathImpl ( RelevantPath path ) {
13631378 exists ( Namespace ns |
1364- result = resolvePath0 ( path , ns , _ ) and
1379+ result = resolvePathImpl0 ( path , ns ) and
13651380 if path = any ( ImplItemNode i ) .getSelfPath ( )
13661381 then
13671382 result instanceof TypeItemNode and
13681383 not result instanceof TraitItemNode
13691384 else
13701385 if path = any ( ImplItemNode i ) .getTraitPath ( )
13711386 then result instanceof TraitItemNode
1372- else any ( )
1387+ else
1388+ if path = any ( PathTypeRepr p ) .getPath ( )
1389+ then result instanceof TypeItemNode
1390+ else any ( )
13731391 |
13741392 pathUsesNamespace ( path , ns )
13751393 or
@@ -1379,11 +1397,36 @@ ItemNode resolvePath(RelevantPath path) {
13791397}
13801398
13811399pragma [ nomagic]
1382- private ItemNode resolvePathQualifier ( RelevantPath path , string name ) {
1383- result = resolvePath ( path .getQualifier ( ) ) and
1400+ private ItemNode resolvePathImplQualifier ( RelevantPath path , string name ) {
1401+ result = resolvePathImpl ( path .getQualifier ( ) ) and
13841402 name = path .getText ( )
13851403}
13861404
1405+ /** Gets the item that `path` resolves to, if any. */
1406+ cached
1407+ ItemNode resolvePath ( RelevantPath path ) {
1408+ result = resolvePathImpl ( path ) and
1409+ // if `path` is the qualifier of a resolvable parent, then we should
1410+ // resolve `path` to something consistent with what the parent resolves to
1411+ (
1412+ not path = any ( Path parent | exists ( resolvePathImpl ( parent ) ) ) .getQualifier ( )
1413+ or
1414+ exists ( ItemNode i , string name |
1415+ i = resolvePathParent ( path , name ) and
1416+ result .getASuccessor ( name ) = i
1417+ )
1418+ )
1419+ }
1420+
1421+ pragma [ nomagic]
1422+ private ItemNode resolvePathParent ( RelevantPath path , string name ) {
1423+ exists ( RelevantPath parent |
1424+ result = resolvePath ( parent ) and
1425+ path = parent .getQualifier ( ) and
1426+ name = parent .getText ( )
1427+ )
1428+ }
1429+
13871430private predicate isUseTreeSubPath ( UseTree tree , RelevantPath path ) {
13881431 path = tree .getPath ( )
13891432 or
@@ -1429,7 +1472,7 @@ private ItemNode resolveUseTreeListItemQualifier(
14291472pragma [ nomagic]
14301473private ItemNode resolveUseTreeListItem ( Use use , UseTree tree ) {
14311474 tree = use .getUseTree ( ) and
1432- result = resolvePath ( tree .getPath ( ) )
1475+ result = resolvePathImpl ( tree .getPath ( ) )
14331476 or
14341477 result = resolveUseTreeListItem ( use , tree , tree .getPath ( ) , _)
14351478}
@@ -1482,21 +1525,13 @@ private predicate externCrateEdge(ExternCrateItemNode ec, string name, CrateItem
14821525
14831526pragma [ nomagic]
14841527private predicate preludeItem ( string name , ItemNode i ) {
1485- exists (
1486- Crate stdOrCore , string stdOrCoreName , ModuleLikeNode mod , ModuleItemNode prelude ,
1487- ModuleItemNode rust
1488- |
1489- stdOrCore .getName ( ) = stdOrCoreName and
1490- stdOrCoreName = [ "std" , "core" ] and
1528+ exists ( Crate stdOrCore , ModuleLikeNode mod , ModuleItemNode prelude , ModuleItemNode rust |
1529+ stdOrCore .getName ( ) = [ "std" , "core" ] and
14911530 mod = stdOrCore .getSourceFile ( ) and
14921531 prelude = mod .getASuccessor ( "prelude" ) and
1493- rust = prelude .getASuccessor ( [ "rust_2015" , "rust_2018" , "rust_2021" , "rust_2024" ] )
1494- |
1532+ rust = prelude .getASuccessor ( [ "rust_2015" , "rust_2018" , "rust_2021" , "rust_2024" ] ) and
14951533 i = rust .getASuccessor ( name ) and
14961534 not name = [ "super" , "self" ]
1497- or
1498- name = stdOrCoreName and
1499- i = stdOrCore
15001535 )
15011536}
15021537
@@ -1513,7 +1548,7 @@ private predicate preludeItem(string name, ItemNode i) {
15131548pragma [ nomagic]
15141549private predicate preludeEdge ( SourceFile f , string name , ItemNode i ) {
15151550 preludeItem ( name , i ) and
1516- not declares ( f , _ , name )
1551+ not declares ( f , i . getNamespace ( ) , name )
15171552}
15181553
15191554pragma [ nomagic]
0 commit comments