diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 72757d90e42..f61248aa731 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -388,6 +388,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { None } + // The `dependency` type is determined by the command line arguments(`--extern`) and + // `private_dep`. However, sometimes the directly dependent crate is not specified by + // `--extern`, in this case, `private-dep` is none during loading. This is equivalent to the + // scenario where the command parameter is set to `public-dependency` + fn is_private_dep(&self, name: &str, private_dep: Option) -> bool { + self.sess.opts.externs.get(name).map_or(private_dep.unwrap_or(false), |e| e.is_private_dep) + && private_dep.unwrap_or(true) + } + fn register_crate( &mut self, host_lib: Option, @@ -402,14 +411,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { let Library { source, metadata } = lib; let crate_root = metadata.get_root(); let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash()); - - let private_dep = self - .sess - .opts - .externs - .get(name.as_str()) - .map_or(private_dep.unwrap_or(false), |e| e.is_private_dep) - && private_dep.unwrap_or(true); + let private_dep = self.is_private_dep(name.as_str(), private_dep); // Claim this crate number and cache it let cnum = self.cstore.intern_stable_crate_id(&crate_root)?; @@ -599,14 +601,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { match result { (LoadResult::Previous(cnum), None) => { + // When `private_dep` is none, it indicates the directly dependent crate. If it is + // not specified by `--extern` on command line parameters, it may be + // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to + // `public-dependency` here. + let private_dep = self.is_private_dep(name.as_str(), private_dep); let data = self.cstore.get_crate_data_mut(cnum); if data.is_proc_macro_crate() { dep_kind = CrateDepKind::MacrosOnly; } data.set_dep_kind(cmp::max(data.dep_kind(), dep_kind)); - if let Some(private_dep) = private_dep { - data.update_and_private_dep(private_dep); - } + data.update_and_private_dep(private_dep); Ok(cnum) } (LoadResult::Loaded(library), host_library) => { diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/bar.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/bar.rs new file mode 100644 index 00000000000..58297c92693 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/bar.rs @@ -0,0 +1,6 @@ +//@ aux-crate:priv:foo=foo.rs +//@ compile-flags: -Zunstable-options + +#![crate_type = "rlib"] +extern crate foo; +pub struct Bar(pub i32); diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/foo.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/foo.rs new file mode 100644 index 00000000000..6fd950619e6 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/foo.rs @@ -0,0 +1,2 @@ +#![crate_type = "rlib"] +pub struct Foo(pub i32); diff --git a/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs b/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs new file mode 100644 index 00000000000..d7ade7f0e96 --- /dev/null +++ b/tests/ui/privacy/pub-priv-dep/priv-dep-issue-122756.rs @@ -0,0 +1,12 @@ +//@ aux-build: bar.rs +//@ aux-build: foo.rs +//@ build-pass + +#![deny(exported_private_dependencies)] + +// Ensure the libbar.rlib is loaded first. If the command line parameter `--extern foo` does not +// exist, previus version would fail to compile +#![crate_type = "rlib"] +extern crate bar; +extern crate foo; +pub fn baz() -> (Option, Option) { (None, None) }