Skip to content

Commit 3527d02

Browse files
committed
Fixed the private-dependency bug: If the directly dependent crate is loaded last and is not configured with --extern, it may be incorrectly set to private-dependency
1 parent c7fed9f commit 3527d02

File tree

5 files changed

+35
-11
lines changed

5 files changed

+35
-11
lines changed

compiler/rustc_metadata/src/creader.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
388388
None
389389
}
390390

391+
// The `dependency` type is determined by the command line arguments(`--extern`) and
392+
// `private_dep`. However, sometimes the directly dependent crate is not specified by
393+
// `--extern`, in this case, `private-dep` is none during loading. This is equivalent to the
394+
// scenario where the command parameter is set to `public-dependency`
395+
fn is_private_dep(&self, name: &str, private_dep: Option<bool>) -> bool {
396+
self.sess.opts.externs.get(name).map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
397+
&& private_dep.unwrap_or(true)
398+
}
399+
391400
fn register_crate(
392401
&mut self,
393402
host_lib: Option<Library>,
@@ -402,14 +411,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
402411
let Library { source, metadata } = lib;
403412
let crate_root = metadata.get_root();
404413
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
405-
406-
let private_dep = self
407-
.sess
408-
.opts
409-
.externs
410-
.get(name.as_str())
411-
.map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
412-
&& private_dep.unwrap_or(true);
414+
let private_dep = self.is_private_dep(name.as_str(), private_dep);
413415

414416
// Claim this crate number and cache it
415417
let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
@@ -599,14 +601,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
599601

600602
match result {
601603
(LoadResult::Previous(cnum), None) => {
604+
// When `private_dep` is none, it indicates the directly dependent crate. If it is
605+
// not specified by `--extern` on command line parameters, it may be
606+
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
607+
// `public-dependency` here.
608+
let private_dep = self.is_private_dep(name.as_str(), private_dep);
602609
let data = self.cstore.get_crate_data_mut(cnum);
603610
if data.is_proc_macro_crate() {
604611
dep_kind = CrateDepKind::MacrosOnly;
605612
}
606613
data.set_dep_kind(cmp::max(data.dep_kind(), dep_kind));
607-
if let Some(private_dep) = private_dep {
608-
data.update_and_private_dep(private_dep);
609-
}
614+
data.update_and_private_dep(private_dep);
610615
Ok(cnum)
611616
}
612617
(LoadResult::Loaded(library), host_library) => {
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include ../tools.mk
2+
3+
# ignore-cross-compile
4+
# only-linux
5+
# only-x86_64
6+
7+
all:
8+
$(RUSTC) --crate-type rlib foo.rs
9+
$(RUSTC) --crate-type rlib bar.rs --extern priv:foo -L all=$(TMPDIR) -Zunstable-options
10+
$(RUSTC) --crate-type rlib baz.rs
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
extern crate foo;
2+
pub struct Bar(pub i32);
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![deny(exported_private_dependencies)]
2+
// Ensure the libbar.rlib is loaded first. If the command line parameter `--extern foo` does not
3+
// exist, previus version would fail to compile
4+
extern crate bar;
5+
extern crate foo;
6+
pub fn baz() -> (Option<foo::Foo>, Option<bar::Bar>) { (None, None) }
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub struct Foo(pub i32);

0 commit comments

Comments
 (0)