@@ -188,6 +188,7 @@ abstract class ItemNode extends Locatable {
188
188
crateDefEdge ( this , name , result , kind )
189
189
or
190
190
crateDependencyEdge ( this , name , result ) and
191
+ not declaresDirectly ( this , TTypeNamespace ( ) , name ) and
191
192
kind .isInternal ( )
192
193
or
193
194
externCrateEdge ( this , name , result ) and
@@ -291,6 +292,7 @@ abstract class ItemNode extends Locatable {
291
292
}
292
293
293
294
/** Gets an _external_ successor named `name`, if any. */
295
+ pragma [ nomagic]
294
296
ItemNode getASuccessor ( string name ) {
295
297
exists ( SuccessorKind kind |
296
298
result = this .getASuccessor ( name , kind ) and
@@ -609,17 +611,17 @@ abstract class ImplOrTraitItemNode extends ItemNode {
609
611
610
612
pragma [ nomagic]
611
613
private TypeParamItemNode resolveTypeParamPathTypeRepr ( PathTypeRepr ptr ) {
612
- result = resolvePath ( ptr .getPath ( ) )
614
+ result = resolvePathImpl ( ptr .getPath ( ) )
613
615
}
614
616
615
617
class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
616
618
Path getSelfPath ( ) { result = super .getSelfTy ( ) .( PathTypeRepr ) .getPath ( ) }
617
619
618
620
Path getTraitPath ( ) { result = super .getTrait ( ) .( PathTypeRepr ) .getPath ( ) }
619
621
620
- TypeItemNode resolveSelfTy ( ) { result = resolvePath ( this .getSelfPath ( ) ) }
622
+ TypeItemNode resolveSelfTy ( ) { result = resolvePathImpl ( this .getSelfPath ( ) ) }
621
623
622
- TraitItemNode resolveTraitTy ( ) { result = resolvePath ( this .getTraitPath ( ) ) }
624
+ TraitItemNode resolveTraitTy ( ) { result = resolvePathImpl ( this .getTraitPath ( ) ) }
623
625
624
626
override AssocItemNode getAnAssocItem ( ) { result = this .getADescendant ( ) }
625
627
@@ -713,7 +715,7 @@ private class ImplTraitTypeReprItemNode extends TypeItemNode instanceof ImplTrai
713
715
}
714
716
715
717
pragma [ nomagic]
716
- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
718
+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
717
719
718
720
override string getName ( ) { result = "(impl trait)" }
719
721
@@ -810,7 +812,7 @@ class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof Trait {
810
812
Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
811
813
812
814
pragma [ nomagic]
813
- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
815
+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
814
816
815
817
override AssocItemNode getAnAssocItem ( ) { result = this .getADescendant ( ) }
816
818
@@ -862,7 +864,7 @@ class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof Trait {
862
864
863
865
class TypeAliasItemNode extends TypeItemNode , AssocItemNode instanceof TypeAlias {
864
866
pragma [ nomagic]
865
- ItemNode resolveAlias ( ) { result = resolvePath ( super .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) ) }
867
+ ItemNode resolveAlias ( ) { result = resolvePathImpl ( super .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) ) }
866
868
867
869
override string getName ( ) { result = TypeAlias .super .getName ( ) .getText ( ) }
868
870
@@ -951,7 +953,7 @@ class TypeParamItemNode extends TypeItemNode instanceof TypeParam {
951
953
Path getABoundPath ( ) { result = super .getATypeBound ( ) .getTypeRepr ( ) .( PathTypeRepr ) .getPath ( ) }
952
954
953
955
pragma [ nomagic]
954
- ItemNode resolveABound ( ) { result = resolvePath ( this .getABoundPath ( ) ) }
956
+ ItemNode resolveABound ( ) { result = resolvePathImpl ( this .getABoundPath ( ) ) }
955
957
956
958
/**
957
959
* Holds if this type parameter has a trait bound. Examples:
@@ -1153,6 +1155,11 @@ private class BuiltinSourceFile extends SourceFileItemNode {
1153
1155
pragma [ nomagic]
1154
1156
private predicate crateDependencyEdge ( SourceFileItemNode file , string name , CrateItemNode dep ) {
1155
1157
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 ( )
1156
1163
}
1157
1164
1158
1165
private predicate useTreeDeclares ( UseTree tree , string name ) {
@@ -1174,15 +1181,24 @@ private predicate useTreeDeclares(UseTree tree, string name) {
1174
1181
1175
1182
/**
1176
1183
* 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.
1179
1185
*/
1180
1186
pragma [ nomagic]
1181
- private predicate declares ( ItemNode item , Namespace ns , string name ) {
1187
+ private predicate declaresDirectly ( ItemNode item , Namespace ns , string name ) {
1182
1188
exists ( ItemNode child , SuccessorKind kind | child = getAChildSuccessor ( item , name , kind ) |
1183
1189
child .getNamespace ( ) = ns and
1184
1190
kind .isInternalOrBoth ( )
1185
1191
)
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 )
1186
1202
or
1187
1203
exists ( ItemNode child |
1188
1204
child .getImmediateParent ( ) = item and
@@ -1306,9 +1322,9 @@ pragma[nomagic]
1306
1322
private predicate isUnqualifiedSelfPath ( RelevantPath path ) { path .isUnqualified ( "Self" ) }
1307
1323
1308
1324
pragma [ nomagic]
1309
- private ItemNode resolvePath0 ( RelevantPath path , Namespace ns , SuccessorKind kind ) {
1325
+ private ItemNode resolvePathImpl0 ( RelevantPath path , Namespace ns ) {
1310
1326
exists ( ItemNode res |
1311
- res = unqualifiedPathLookup ( path , ns , kind ) and
1327
+ res = unqualifiedPathLookup ( path , ns , _ ) and
1312
1328
if
1313
1329
not any ( RelevantPath parent ) .getQualifier ( ) = path and
1314
1330
isUnqualifiedSelfPath ( path ) and
@@ -1317,13 +1333,13 @@ private ItemNode resolvePath0(RelevantPath path, Namespace ns, SuccessorKind kin
1317
1333
else result = res
1318
1334
)
1319
1335
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
1322
1338
result = getASuccessor ( q , name , ns , kind ) and
1323
1339
kind .isExternalOrBoth ( )
1324
1340
)
1325
1341
or
1326
- result = resolveUseTreeListItem ( _, _, path , kind ) and
1342
+ result = resolveUseTreeListItem ( _, _, path , _ ) and
1327
1343
ns = result .getNamespace ( )
1328
1344
}
1329
1345
@@ -1357,19 +1373,21 @@ private predicate pathUsesNamespace(Path p, Namespace n) {
1357
1373
)
1358
1374
}
1359
1375
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 ) {
1363
1378
exists ( Namespace ns |
1364
- result = resolvePath0 ( path , ns , _ ) and
1379
+ result = resolvePathImpl0 ( path , ns ) and
1365
1380
if path = any ( ImplItemNode i ) .getSelfPath ( )
1366
1381
then
1367
1382
result instanceof TypeItemNode and
1368
1383
not result instanceof TraitItemNode
1369
1384
else
1370
1385
if path = any ( ImplItemNode i ) .getTraitPath ( )
1371
1386
then result instanceof TraitItemNode
1372
- else any ( )
1387
+ else
1388
+ if path = any ( PathTypeRepr p ) .getPath ( )
1389
+ then result instanceof TypeItemNode
1390
+ else any ( )
1373
1391
|
1374
1392
pathUsesNamespace ( path , ns )
1375
1393
or
@@ -1379,11 +1397,36 @@ ItemNode resolvePath(RelevantPath path) {
1379
1397
}
1380
1398
1381
1399
pragma [ 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
1384
1402
name = path .getText ( )
1385
1403
}
1386
1404
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
+
1387
1430
private predicate isUseTreeSubPath ( UseTree tree , RelevantPath path ) {
1388
1431
path = tree .getPath ( )
1389
1432
or
@@ -1429,7 +1472,7 @@ private ItemNode resolveUseTreeListItemQualifier(
1429
1472
pragma [ nomagic]
1430
1473
private ItemNode resolveUseTreeListItem ( Use use , UseTree tree ) {
1431
1474
tree = use .getUseTree ( ) and
1432
- result = resolvePath ( tree .getPath ( ) )
1475
+ result = resolvePathImpl ( tree .getPath ( ) )
1433
1476
or
1434
1477
result = resolveUseTreeListItem ( use , tree , tree .getPath ( ) , _)
1435
1478
}
@@ -1482,21 +1525,13 @@ private predicate externCrateEdge(ExternCrateItemNode ec, string name, CrateItem
1482
1525
1483
1526
pragma [ nomagic]
1484
1527
private 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
1491
1530
mod = stdOrCore .getSourceFile ( ) and
1492
1531
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
1495
1533
i = rust .getASuccessor ( name ) and
1496
1534
not name = [ "super" , "self" ]
1497
- or
1498
- name = stdOrCoreName and
1499
- i = stdOrCore
1500
1535
)
1501
1536
}
1502
1537
@@ -1513,7 +1548,7 @@ private predicate preludeItem(string name, ItemNode i) {
1513
1548
pragma [ nomagic]
1514
1549
private predicate preludeEdge ( SourceFile f , string name , ItemNode i ) {
1515
1550
preludeItem ( name , i ) and
1516
- not declares ( f , _ , name )
1551
+ not declares ( f , i . getNamespace ( ) , name )
1517
1552
}
1518
1553
1519
1554
pragma [ nomagic]
0 commit comments