@@ -208,6 +208,7 @@ abstract class ItemNode extends Locatable {
208
208
crateDefEdge ( this , name , result , kind )
209
209
or
210
210
crateDependencyEdge ( this , name , result ) and
211
+ not declaresDirectly ( this , TTypeNamespace ( ) , name ) and
211
212
kind .isInternal ( )
212
213
or
213
214
externCrateEdge ( this , name , result ) and
@@ -311,6 +312,7 @@ abstract class ItemNode extends Locatable {
311
312
}
312
313
313
314
/** Gets an _external_ successor named `name`, if any. */
315
+ pragma [ nomagic]
314
316
ItemNode getASuccessor ( string name ) {
315
317
exists ( SuccessorKind kind |
316
318
result = this .getASuccessor ( name , kind ) and
@@ -629,17 +631,17 @@ abstract class ImplOrTraitItemNode extends ItemNode {
629
631
630
632
pragma [ nomagic]
631
633
private TypeParamItemNode resolveTypeParamPathTypeRepr ( PathTypeRepr ptr ) {
632
- result = resolvePath ( ptr .getPath ( ) )
634
+ result = resolvePathImpl ( ptr .getPath ( ) )
633
635
}
634
636
635
637
class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
636
638
Path getSelfPath ( ) { result = super .getSelfTy ( ) .( PathTypeRepr ) .getPath ( ) }
637
639
638
640
Path getTraitPath ( ) { result = super .getTrait ( ) .( PathTypeRepr ) .getPath ( ) }
639
641
640
- TypeItemNode resolveSelfTy ( ) { result = resolvePath ( this .getSelfPath ( ) ) }
642
+ TypeItemNode resolveSelfTy ( ) { result = resolvePathImpl ( this .getSelfPath ( ) ) }
641
643
642
- TraitItemNode resolveTraitTy ( ) { result = resolvePath ( this .getTraitPath ( ) ) }
644
+ TraitItemNode resolveTraitTy ( ) { result = resolvePathImpl ( this .getTraitPath ( ) ) }
643
645
644
646
override AssocItemNode getAnAssocItem ( ) { result = this .getADescendant ( ) }
645
647
@@ -733,7 +735,7 @@ private class ImplTraitTypeReprItemNode extends TypeItemNode instanceof ImplTrai
733
735
}
734
736
735
737
pragma [ nomagic]
736
- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
738
+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
737
739
738
740
override string getName ( ) { result = "(impl trait)" }
739
741
@@ -830,7 +832,7 @@ class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof Trait {
830
832
Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
831
833
832
834
pragma [ nomagic]
833
- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
835
+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
834
836
835
837
override AssocItemNode getAnAssocItem ( ) { result = this .getADescendant ( ) }
836
838
@@ -882,7 +884,7 @@ class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof Trait {
882
884
883
885
class TypeAliasItemNode extends TypeItemNode , AssocItemNode instanceof TypeAlias {
884
886
pragma [ nomagic]
885
- ItemNode resolveAlias ( ) { result = resolvePath ( super .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) ) }
887
+ ItemNode resolveAlias ( ) { result = resolvePathImpl ( super .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) ) }
886
888
887
889
override string getName ( ) { result = TypeAlias .super .getName ( ) .getText ( ) }
888
890
@@ -971,7 +973,7 @@ class TypeParamItemNode extends TypeItemNode instanceof TypeParam {
971
973
Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
972
974
973
975
pragma [ nomagic]
974
- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
976
+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
975
977
976
978
/**
977
979
* Holds if this type parameter has a trait bound. Examples:
@@ -1173,6 +1175,11 @@ private class BuiltinSourceFile extends SourceFileItemNode {
1173
1175
pragma [ nomagic]
1174
1176
private predicate crateDependencyEdge ( SourceFileItemNode file , string name , CrateItemNode dep ) {
1175
1177
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 ( )
1176
1183
}
1177
1184
1178
1185
private predicate useTreeDeclares ( UseTree tree , string name ) {
@@ -1194,15 +1201,24 @@ private predicate useTreeDeclares(UseTree tree, string name) {
1194
1201
1195
1202
/**
1196
1203
* 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.
1199
1205
*/
1200
1206
pragma [ nomagic]
1201
- private predicate declares ( ItemNode item , Namespace ns , string name ) {
1207
+ private predicate declaresDirectly ( ItemNode item , Namespace ns , string name ) {
1202
1208
exists ( ItemNode child , SuccessorKind kind | child = getAChildSuccessor ( item , name , kind ) |
1203
1209
child .getNamespace ( ) = ns and
1204
1210
kind .isInternalOrBoth ( )
1205
1211
)
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 )
1206
1222
or
1207
1223
exists ( ItemNode child |
1208
1224
child .getImmediateParent ( ) = item and
@@ -1326,9 +1342,9 @@ pragma[nomagic]
1326
1342
private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
1327
1343
1328
1344
pragma [ nomagic]
1329
- private ItemNode resolvePath0 ( RelevantPath path , Namespace ns , SuccessorKind kind ) {
1345
+ private ItemNode resolvePathImpl0 ( RelevantPath path , Namespace ns ) {
1330
1346
exists ( ItemNode res |
1331
- res = unqualifiedPathLookup ( path , ns , kind ) and
1347
+ res = unqualifiedPathLookup ( path , ns , _ ) and
1332
1348
if
1333
1349
not any ( RelevantPath parent ) .getQualifier ( ) = path and
1334
1350
isUnqualifiedSelfPath ( path ) and
@@ -1337,13 +1353,13 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns, SuccessorKind kin
1337
1353
else result = res
1338
1354
)
1339
1355
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
1342
1358
result = getASuccessor ( q , name , ns , kind ) and
1343
1359
kind .isExternalOrBoth ( )
1344
1360
)
1345
1361
or
1346
- result = resolveUseTreeListItem ( _, _, path , kind ) and
1362
+ result = resolveUseTreeListItem ( _, _, path , _ ) and
1347
1363
ns = result .getNamespace ( )
1348
1364
}
1349
1365
@@ -1377,19 +1393,21 @@ private predicate pathUsesNamespace(Path p, Namespace n) {
1377
1393
)
1378
1394
}
1379
1395
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 ) {
1383
1398
exists ( Namespace ns |
1384
- result = resolvePath0 ( path , ns , _ ) and
1399
+ result = resolvePathImpl0 ( path , ns ) and
1385
1400
if path = any ( ImplItemNode i ) .getSelfPath ( )
1386
1401
then
1387
1402
result instanceof TypeItemNode and
1388
1403
not result instanceof TraitItemNode
1389
1404
else
1390
1405
if path = any ( ImplItemNode i ) .getTraitPath ( )
1391
1406
then result instanceof TraitItemNode
1392
- else any ( )
1407
+ else
1408
+ if path = any ( PathTypeRepr p ) .getPath ( )
1409
+ then result instanceof TypeItemNode
1410
+ else any ( )
1393
1411
|
1394
1412
pathUsesNamespace ( path , ns )
1395
1413
or
@@ -1399,11 +1417,36 @@ ItemNode resolvePath(RelevantPath path) {
1399
1417
}
1400
1418
1401
1419
pragma [ 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
1404
1422
name = path .getText ( )
1405
1423
}
1406
1424
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
+
1407
1450
private predicate isUseTreeSubPath ( UseTree tree , RelevantPath path ) {
1408
1451
path = tree .getPath ( )
1409
1452
or
@@ -1449,7 +1492,7 @@ private ItemNode resolveUseTreeListItemQualifier(
1449
1492
pragma [ nomagic]
1450
1493
private ItemNode resolveUseTreeListItem ( Use use , UseTree tree ) {
1451
1494
tree = use .getUseTree ( ) and
1452
- result = resolvePath ( tree .getPath ( ) )
1495
+ result = resolvePathImpl ( tree .getPath ( ) )
1453
1496
or
1454
1497
result = resolveUseTreeListItem ( use , tree , tree .getPath ( ) , _)
1455
1498
}
@@ -1502,21 +1545,13 @@ private predicate externCrateEdge(ExternCrateItemNode ec, string name, CrateItem
1502
1545
1503
1546
pragma [ nomagic]
1504
1547
private 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
1511
1550
mod = stdOrCore .getSourceFile ( ) and
1512
1551
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
1515
1553
i = rust .getASuccessor ( name ) and
1516
1554
not name = [ "super" , "self" ]
1517
- or
1518
- name = stdOrCoreName and
1519
- i = stdOrCore
1520
1555
)
1521
1556
}
1522
1557
@@ -1533,7 +1568,7 @@ private predicate preludeItem(string name, ItemNode i) {
1533
1568
pragma [ nomagic]
1534
1569
private predicate preludeEdge ( SourceFile f , string name , ItemNode i ) {
1535
1570
preludeItem ( name , i ) and
1536
- not declares ( f , _ , name )
1571
+ not declares ( f , i . getNamespace ( ) , name )
1537
1572
}
1538
1573
1539
1574
pragma [ nomagic]
0 commit comments