@@ -241,6 +241,8 @@ private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
241241
242242 override Visibility getVisibility ( ) { none ( ) }
243243
244+ override predicate isPublic ( ) { any ( ) }
245+
244246 override TypeParam getTypeParam ( int i ) { none ( ) }
245247}
246248
@@ -286,6 +288,8 @@ class CrateItemNode extends ItemNode instanceof Crate {
286288
287289 override Visibility getVisibility ( ) { none ( ) }
288290
291+ override predicate isPublic ( ) { any ( ) }
292+
289293 override TypeParam getTypeParam ( int i ) { none ( ) }
290294}
291295
@@ -663,7 +667,6 @@ private predicate fileImport(Module m, SourceFile f) {
663667 */
664668pragma [ nomagic]
665669private predicate fileImportEdge ( Module mod , string name , ItemNode item ) {
666- item .isPublic ( ) and
667670 exists ( SourceFileItemNode f |
668671 fileImport ( mod , f ) and
669672 item = f .getASuccessor ( name )
@@ -675,8 +678,7 @@ private predicate fileImportEdge(Module mod, string name, ItemNode item) {
675678 */
676679pragma [ nomagic]
677680private predicate crateDefEdge ( CrateItemNode c , string name , ItemNode i ) {
678- i = c .getModuleNode ( ) .getASuccessor ( name ) and
679- i .isPublic ( )
681+ i = c .getModuleNode ( ) .getASuccessor ( name )
680682}
681683
682684/**
@@ -837,9 +839,8 @@ private predicate pathUsesNamespace(Path p, Namespace n) {
837839 )
838840}
839841
840- /** Gets the item that `path` resolves to, if any. */
841- cached
842- ItemNode resolvePath ( RelevantPath path ) {
842+ pragma [ nomagic]
843+ private ItemNode resolvePath1 ( RelevantPath path ) {
843844 exists ( Namespace ns | result = resolvePath0 ( path , ns ) |
844845 pathUsesNamespace ( path , ns )
845846 or
@@ -848,6 +849,47 @@ ItemNode resolvePath(RelevantPath path) {
848849 )
849850}
850851
852+ pragma [ nomagic]
853+ private ItemNode resolvePathPrivate (
854+ RelevantPath path , ModuleLikeNode itemParent , ModuleLikeNode pathParent
855+ ) {
856+ result = resolvePath1 ( path ) and
857+ itemParent = result .getImmediateParentModule ( ) and
858+ not result .isPublic ( ) and
859+ (
860+ pathParent .getADescendant ( ) = path
861+ or
862+ pathParent = any ( ItemNode mid | path = mid .getADescendant ( ) ) .getImmediateParentModule ( )
863+ )
864+ }
865+
866+ /**
867+ * Gets a module that has access to private items defined inside `itemParent`.
868+ *
869+ * According to
870+ *
871+ * 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
872+ *
873+ * this is either `itemParent` itself or any (transitive) child of `itemParent`.
874+ */
875+ pragma [ nomagic]
876+ private ModuleLikeNode getAPrivateVisibleModule ( ModuleLikeNode itemParent ) {
877+ exists ( resolvePathPrivate ( _, itemParent , _) ) and
878+ result .getImmediateParentModule * ( ) = itemParent
879+ }
880+
881+ /** Gets the item that `path` resolves to, if any. */
882+ cached
883+ ItemNode resolvePath ( RelevantPath path ) {
884+ result = resolvePath1 ( path ) and
885+ result .isPublic ( )
886+ or
887+ exists ( ModuleLikeNode itemParent , ModuleLikeNode pathParent |
888+ result = resolvePathPrivate ( path , itemParent , pathParent ) and
889+ pathParent = getAPrivateVisibleModule ( itemParent )
890+ )
891+ }
892+
851893pragma [ nomagic]
852894private ItemNode resolvePathQualifier ( RelevantPath path , string name ) {
853895 result = resolvePath ( path .getQualifier ( ) ) and
0 commit comments