diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index fe75ee8b37b..6caa1032ba3 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -66,6 +66,7 @@ where location: ExternLocation::ExactPaths(locations), is_private_dep: false, add_prelude: true, + nounused_dep: false, } } diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index e5d0cd28925..e8cdae7fd25 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -907,6 +907,10 @@ impl<'a> CrateLoader<'a> { // Don't worry about pathless `--extern foo` sysroot references continue; } + if entry.nounused_dep { + // We're not worried about this one + continue; + } let name_interned = Symbol::intern(name); if self.used_extern_options.contains(&name_interned) { continue; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 12c5c4445d4..925f6bfd93d 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -474,6 +474,11 @@ pub struct ExternEntry { /// This can be disabled with the `noprelude` option like /// `--extern noprelude:name`. pub add_prelude: bool, + /// The extern entry shouldn't be considered for unused dependency warnings. + /// + /// `--extern nounused:std=/path/to/lib/libstd.rlib`. This is used to + /// suppress `unused-crate-dependencies` warnings. + pub nounused_dep: bool, } #[derive(Clone, Debug)] @@ -512,7 +517,7 @@ impl Externs { impl ExternEntry { fn new(location: ExternLocation) -> ExternEntry { - ExternEntry { location, is_private_dep: false, add_prelude: false } + ExternEntry { location, is_private_dep: false, add_prelude: false, nounused_dep: false } } pub fn files(&self) -> Option> { @@ -2131,6 +2136,7 @@ pub fn parse_externs( let mut is_private_dep = false; let mut add_prelude = true; + let mut nounused_dep = false; if let Some(opts) = options { if !is_unstable_enabled { early_error( @@ -2152,6 +2158,7 @@ pub fn parse_externs( ); } } + "nounused" => nounused_dep = true, _ => early_error(error_format, &format!("unknown --extern option `{opt}`")), } } @@ -2160,6 +2167,8 @@ pub fn parse_externs( // Crates start out being not private, and go to being private `priv` // is specified. entry.is_private_dep |= is_private_dep; + // likewise `nounused` + entry.nounused_dep |= nounused_dep; // If any flag is missing `noprelude`, then add to the prelude. entry.add_prelude |= add_prelude; } diff --git a/src/test/ui/extern-flag/no-nounused.rs b/src/test/ui/extern-flag/no-nounused.rs new file mode 100644 index 00000000000..5ec75595243 --- /dev/null +++ b/src/test/ui/extern-flag/no-nounused.rs @@ -0,0 +1,6 @@ +// aux-crate:somedep=somedep.rs +// compile-flags: -Zunstable-options -Dunused-crate-dependencies +// edition:2018 + +fn main() { //~ ERROR external crate `somedep` unused in `no_nounused` +} diff --git a/src/test/ui/extern-flag/no-nounused.stderr b/src/test/ui/extern-flag/no-nounused.stderr new file mode 100644 index 00000000000..6446c53236c --- /dev/null +++ b/src/test/ui/extern-flag/no-nounused.stderr @@ -0,0 +1,10 @@ +error: external crate `somedep` unused in `no_nounused`: remove the dependency or add `use somedep as _;` + --> $DIR/no-nounused.rs:5:1 + | +LL | fn main() { + | ^ + | + = note: requested on the command line with `-D unused-crate-dependencies` + +error: aborting due to previous error + diff --git a/src/test/ui/extern-flag/nounused.rs b/src/test/ui/extern-flag/nounused.rs new file mode 100644 index 00000000000..2513986bbec --- /dev/null +++ b/src/test/ui/extern-flag/nounused.rs @@ -0,0 +1,7 @@ +// check-pass +// aux-crate:nounused:somedep=somedep.rs +// compile-flags: -Zunstable-options -Dunused-crate-dependencies +// edition:2018 + +fn main() { +}