about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_metadata/src/creader.rs31
-rw-r--r--tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs3
-rw-r--r--tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr14
-rw-r--r--tests/ui/privacy/pub-priv-dep/shared_indirect.rs3
-rw-r--r--tests/ui/privacy/pub-priv-dep/shared_indirect.stderr14
5 files changed, 56 insertions, 9 deletions
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index b94e32e17d4..58ff2425748 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -168,7 +168,10 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
 enum CrateOrigin<'a> {
     /// This crate was a dependency of another crate.
     IndirectDependency {
+        /// Where this dependency was included from.
         dep_root: &'a CratePaths,
+        /// True if the parent is private, meaning the dependent should also be private.
+        parent_private: bool,
         /// Dependency info about this crate.
         dep: &'a CrateDep,
     },
@@ -194,6 +197,17 @@ impl<'a> CrateOrigin<'a> {
             _ => None,
         }
     }
+
+    /// `Some(true)` if the dependency is private or its parent is private, `Some(false)` if the
+    /// dependency is not private, `None` if it could not be determined.
+    fn private_dep(&self) -> Option<bool> {
+        match self {
+            CrateOrigin::IndirectDependency { parent_private, dep, .. } => {
+                Some(dep.is_private || *parent_private)
+            }
+            _ => None,
+        }
+    }
 }
 
 impl CStore {
@@ -585,7 +599,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
             &crate_paths
         };
 
-        let cnum_map = self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind)?;
+        let cnum_map =
+            self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind, private_dep)?;
 
         let raw_proc_macros = if crate_root.is_proc_macro_crate() {
             let temp_root;
@@ -722,7 +737,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         let host_hash = dep.map(|d| d.host_hash).flatten();
         let extra_filename = dep.map(|d| &d.extra_filename[..]);
         let path_kind = if dep.is_some() { PathKind::Dependency } else { PathKind::Crate };
-        let private_dep = dep.map(|d| d.is_private);
+        let private_dep = origin.private_dep();
 
         let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
             (LoadResult::Previous(cnum), None)
@@ -819,6 +834,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         metadata: &MetadataBlob,
         krate: CrateNum,
         dep_kind: CrateDepKind,
+        parent_is_private: bool,
     ) -> Result<CrateNumMap, CrateError> {
         debug!(
             "resolving deps of external crate `{}` with dep root `{}`",
@@ -837,11 +853,12 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         crate_num_map.push(krate);
         for dep in deps {
             info!(
-                "resolving dep `{}`->`{}` hash: `{}` extra filename: `{}`",
+                "resolving dep `{}`->`{}` hash: `{}` extra filename: `{}` private {}",
                 crate_root.name(),
                 dep.name,
                 dep.hash,
-                dep.extra_filename
+                dep.extra_filename,
+                dep.is_private,
             );
             let dep_kind = match dep_kind {
                 CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly,
@@ -850,7 +867,11 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
             let cnum = self.maybe_resolve_crate(
                 dep.name,
                 dep_kind,
-                CrateOrigin::IndirectDependency { dep_root, dep: &dep },
+                CrateOrigin::IndirectDependency {
+                    dep_root,
+                    parent_private: parent_is_private,
+                    dep: &dep,
+                },
             )?;
             crate_num_map.push(cnum);
         }
diff --git a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs
index 3c6e9825e72..136e0ceeb5b 100644
--- a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs
+++ b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.rs
@@ -1,6 +1,5 @@
 //@ aux-crate:priv:reexport=reexport.rs
 //@ compile-flags: -Zunstable-options
-//@ check-pass
 
 // Checks the behavior of a reexported item from a private dependency.
 
@@ -9,7 +8,7 @@
 
 extern crate reexport;
 
-// FIXME: This should trigger.
 pub fn leaks_priv() -> reexport::Shared {
+    //~^ ERROR type `Shared` from private dependency 'shared' in public interface
     reexport::Shared
 }
diff --git a/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr
new file mode 100644
index 00000000000..f1573283ff2
--- /dev/null
+++ b/tests/ui/privacy/pub-priv-dep/reexport_from_priv.stderr
@@ -0,0 +1,14 @@
+error: type `Shared` from private dependency 'shared' in public interface
+  --> $DIR/reexport_from_priv.rs:11:1
+   |
+LL | pub fn leaks_priv() -> reexport::Shared {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/reexport_from_priv.rs:7:9
+   |
+LL | #![deny(exported_private_dependencies)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/privacy/pub-priv-dep/shared_indirect.rs b/tests/ui/privacy/pub-priv-dep/shared_indirect.rs
index 34b624b4a1a..2fe66ae80cf 100644
--- a/tests/ui/privacy/pub-priv-dep/shared_indirect.rs
+++ b/tests/ui/privacy/pub-priv-dep/shared_indirect.rs
@@ -1,7 +1,6 @@
 //@ aux-crate:priv:shared=shared.rs
 //@ aux-crate:priv:indirect1=indirect1.rs
 //@ compile-flags: -Zunstable-options
-//@ check-pass
 
 // A shared dependency, where it is only indirectly public.
 //
@@ -23,7 +22,7 @@
 extern crate shared;
 extern crate indirect1;
 
-// FIXME: This should trigger.
 pub fn leaks_priv() -> shared::Shared {
+    //~^ ERROR type `Shared` from private dependency 'shared' in public interface
     shared::Shared
 }
diff --git a/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr b/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr
new file mode 100644
index 00000000000..dbc534713d1
--- /dev/null
+++ b/tests/ui/privacy/pub-priv-dep/shared_indirect.stderr
@@ -0,0 +1,14 @@
+error: type `Shared` from private dependency 'shared' in public interface
+  --> $DIR/shared_indirect.rs:25:1
+   |
+LL | pub fn leaks_priv() -> shared::Shared {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/shared_indirect.rs:20:9
+   |
+LL | #![deny(exported_private_dependencies)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+