@@ -229,6 +229,8 @@ private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
229229
230230 override Visibility getVisibility ( ) { none ( ) }
231231
232+ override predicate isPublic ( ) { any ( ) }
233+
232234 override TypeParam getTypeParam ( int i ) { none ( ) }
233235}
234236
@@ -274,6 +276,8 @@ class CrateItemNode extends ItemNode instanceof Crate {
274276
275277 override Visibility getVisibility ( ) { none ( ) }
276278
279+ override predicate isPublic ( ) { any ( ) }
280+
277281 override TypeParam getTypeParam ( int i ) { none ( ) }
278282}
279283
@@ -651,7 +655,6 @@ private predicate fileImport(Module m, SourceFile f) {
651655 */
652656pragma [ nomagic]
653657private predicate fileImportEdge ( Module mod , string name , ItemNode item ) {
654- item .isPublic ( ) and
655658 exists ( SourceFileItemNode f |
656659 fileImport ( mod , f ) and
657660 item = f .getASuccessor ( name )
@@ -663,8 +666,7 @@ private predicate fileImportEdge(Module mod, string name, ItemNode item) {
663666 */
664667pragma [ nomagic]
665668private predicate crateDefEdge ( CrateItemNode c , string name , ItemNode i ) {
666- i = c .getModuleNode ( ) .getASuccessor ( name ) and
667- i .isPublic ( )
669+ i = c .getModuleNode ( ) .getASuccessor ( name )
668670}
669671
670672/**
@@ -831,9 +833,8 @@ private predicate pathUsesNamespace(Path p, Namespace n) {
831833 )
832834}
833835
834- /** Gets the item that `path` resolves to, if any. */
835- cached
836- ItemNode resolvePath ( RelevantPath path ) {
836+ pragma [ nomagic]
837+ private ItemNode resolvePath1 ( RelevantPath path ) {
837838 exists ( Namespace ns | result = resolvePath0 ( path , ns ) |
838839 pathUsesNamespace ( path , ns )
839840 or
@@ -842,6 +843,47 @@ ItemNode resolvePath(RelevantPath path) {
842843 )
843844}
844845
846+ pragma [ nomagic]
847+ private ItemNode resolvePathPrivate (
848+ RelevantPath path , ModuleLikeNode itemParent , ModuleLikeNode pathParent
849+ ) {
850+ result = resolvePath1 ( path ) and
851+ itemParent = result .getImmediateParentModule ( ) and
852+ not result .isPublic ( ) and
853+ (
854+ pathParent .getADescendant ( ) = path
855+ or
856+ pathParent = any ( ItemNode mid | path = mid .getADescendant ( ) ) .getImmediateParentModule ( )
857+ )
858+ }
859+
860+ /**
861+ * Gets a module that has access to private items defined inside `itemParent`.
862+ *
863+ * According to
864+ *
865+ * https://web.mit.edu/rust-lang_v1.25/arch/amd64_ubuntu1404/share/doc/rust/html/book/second-edition/ch07-02-controlling-visibility-with-pub.html#privacy-rules
866+ *
867+ * this is either `itemParent` itself or any (transitive) child of `itemParent`.
868+ */
869+ pragma [ nomagic]
870+ private ModuleLikeNode getAPrivateVisibleModule ( ModuleLikeNode itemParent ) {
871+ exists ( resolvePathPrivate ( _, itemParent , _) ) and
872+ result .getImmediateParentModule * ( ) = itemParent
873+ }
874+
875+ /** Gets the item that `path` resolves to, if any. */
876+ cached
877+ ItemNode resolvePath ( RelevantPath path ) {
878+ result = resolvePath1 ( path ) and
879+ result .isPublic ( )
880+ or
881+ exists ( ModuleLikeNode itemParent , ModuleLikeNode pathParent |
882+ result = resolvePathPrivate ( path , itemParent , pathParent ) and
883+ pathParent = getAPrivateVisibleModule ( itemParent )
884+ )
885+ }
886+
845887pragma [ nomagic]
846888private ItemNode resolvePathQualifier ( RelevantPath path , string name ) {
847889 result = resolvePath ( path .getQualifier ( ) ) and
0 commit comments