@@ -72,9 +72,9 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki
72
72
if item instanceof ImplOrTraitItemNode and result instanceof AssocItem
73
73
then kind .isExternal ( )
74
74
else
75
- if result instanceof Use
76
- then kind .isInternal ( )
77
- else kind .isBoth ( )
75
+ if result . isPublic ( )
76
+ then kind .isBoth ( )
77
+ else kind .isInternal ( )
78
78
)
79
79
}
80
80
@@ -165,6 +165,20 @@ abstract class ItemNode extends Locatable {
165
165
/** Gets the visibility of this item, if any. */
166
166
abstract Visibility getVisibility ( ) ;
167
167
168
+ /**
169
+ * Holds if this item is public.
170
+ *
171
+ * This is the case when this item either has `pub` visibility (but is not
172
+ * a `use`; a `use` itself is not visible from the outside), or when this
173
+ * item is a variant.
174
+ */
175
+ predicate isPublic ( ) {
176
+ exists ( this .getVisibility ( ) ) and
177
+ not this instanceof Use
178
+ or
179
+ this instanceof Variant
180
+ }
181
+
168
182
/** Gets the `i`th type parameter of this item, if any. */
169
183
abstract TypeParam getTypeParam ( int i ) ;
170
184
@@ -380,9 +394,7 @@ abstract private class ModuleLikeNode extends ItemNode {
380
394
381
395
private class SourceFileItemNode extends ModuleLikeNode , SourceFile {
382
396
pragma [ nomagic]
383
- ModuleLikeNode getSuper ( ) {
384
- result = any ( ModuleItemNode mod | fileImport ( mod , this ) ) .getASuccessor ( "super" )
385
- }
397
+ ModuleLikeNode getSuper ( ) { fileImport ( result .getAnItemInScope ( ) , this ) }
386
398
387
399
override string getName ( ) { result = "(source file)" }
388
400
@@ -1300,7 +1312,8 @@ private predicate useTreeDeclares(UseTree tree, string name) {
1300
1312
*/
1301
1313
pragma [ nomagic]
1302
1314
private predicate declaresDirectly ( ItemNode item , Namespace ns , string name ) {
1303
- exists ( ItemNode child , SuccessorKind kind | child = getAChildSuccessor ( item , name , kind ) |
1315
+ exists ( ItemNode child , SuccessorKind kind |
1316
+ child = getAChildSuccessor ( item , name , kind ) and
1304
1317
child .getNamespace ( ) = ns and
1305
1318
kind .isInternalOrBoth ( )
1306
1319
)
@@ -1491,6 +1504,13 @@ private ItemNode resolvePathCandQualifier(RelevantPath qualifier, RelevantPath p
1491
1504
name = path .getText ( )
1492
1505
}
1493
1506
1507
+ pragma [ nomagic]
1508
+ private Crate getCrate0 ( Locatable l ) { result .getASourceFile ( ) .getFile ( ) = l .getFile ( ) }
1509
+
1510
+ bindingset [ l]
1511
+ pragma [ inline_late]
1512
+ private Crate getCrate ( Locatable l ) { result = getCrate0 ( l ) }
1513
+
1494
1514
/**
1495
1515
* Gets the item that `path` resolves to in `ns` when `qualifier` is the
1496
1516
* qualifier of `path` and `qualifier` resolves to `q`, if any.
@@ -1501,8 +1521,17 @@ private ItemNode resolvePathCandQualified(
1501
1521
) {
1502
1522
exists ( string name , SuccessorKind kind |
1503
1523
q = resolvePathCandQualifier ( qualifier , path , name ) and
1504
- result = getASuccessor ( q , name , ns , kind ) and
1524
+ result = getASuccessor ( q , name , ns , kind )
1525
+ |
1505
1526
kind .isExternalOrBoth ( )
1527
+ or
1528
+ // Non-public items are visible to paths in descendant modules of the declaring
1529
+ // module; the declaration may happen via a `use` statement, where the item
1530
+ // being used is _not_ itself in an ancestor module, and we currently don't track
1531
+ // that information in `getASuccessor`. So, for simplicity, we allow for non-public
1532
+ // items when the path and the item are in the same crate.
1533
+ getCrate ( path ) = getCrate ( result ) and
1534
+ not result instanceof TypeParam
1506
1535
)
1507
1536
}
1508
1537
@@ -1646,10 +1675,12 @@ private ItemNode resolveUseTreeListItemQualifier(
1646
1675
1647
1676
pragma [ nomagic]
1648
1677
private ItemNode resolveUseTreeListItem ( Use use , UseTree tree ) {
1649
- tree = use .getUseTree ( ) and
1650
- result = resolvePathCand ( tree .getPath ( ) )
1651
- or
1652
- result = resolveUseTreeListItem ( use , tree , tree .getPath ( ) , _)
1678
+ exists ( Path path | path = tree .getPath ( ) |
1679
+ tree = use .getUseTree ( ) and
1680
+ result = resolvePathCand ( path )
1681
+ or
1682
+ result = resolveUseTreeListItem ( use , tree , path , _)
1683
+ )
1653
1684
}
1654
1685
1655
1686
/** Holds if `use` imports `item` as `name`. */
@@ -1673,7 +1704,10 @@ private predicate useImportEdge(Use use, string name, ItemNode item, SuccessorKi
1673
1704
item = used and
1674
1705
(
1675
1706
not tree .hasRename ( ) and
1676
- name = item .getName ( )
1707
+ exists ( string pathName |
1708
+ pathName = tree .getPath ( ) .getText ( ) and
1709
+ if pathName = "self" then name = item .getName ( ) else name = pathName
1710
+ )
1677
1711
or
1678
1712
exists ( Rename rename | rename = tree .getRename ( ) |
1679
1713
name = rename .getName ( ) .getText ( )
0 commit comments