diff --git a/Cargo.lock b/Cargo.lock index aefd40bfaa59e..5b2d86345978a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3505,7 +3505,6 @@ version = "0.0.0" dependencies = [ "log", "rustc_ast", - "rustc_data_structures", "rustc_span", ] @@ -3522,7 +3521,6 @@ dependencies = [ "rustc_session", "rustc_span", "serialize", - "smallvec 1.0.0", ] [[package]] @@ -3781,7 +3779,6 @@ dependencies = [ "rustc_ast", "rustc_attr", "rustc_data_structures", - "rustc_error_codes", "rustc_errors", "rustc_hir", "rustc_index", @@ -3948,7 +3945,6 @@ dependencies = [ "rustc_hir", "rustc_index", "rustc_infer", - "rustc_macros", "rustc_session", "rustc_span", "rustc_target", @@ -3985,7 +3981,6 @@ dependencies = [ "rustc_attr", "rustc_data_structures", "rustc_errors", - "rustc_feature", "rustc_hir", "rustc_index", "rustc_infer", @@ -4039,7 +4034,6 @@ dependencies = [ "rustc_expand", "rustc_feature", "rustc_hir", - "rustc_infer", "rustc_metadata", "rustc_session", "rustc_span", @@ -4075,7 +4069,6 @@ dependencies = [ "rustc_errors", "rustc_feature", "rustc_fs_util", - "rustc_index", "rustc_span", "rustc_target", "serialize", @@ -4129,9 +4122,7 @@ dependencies = [ "rustc_data_structures", "rustc_hir", "rustc_infer", - "rustc_macros", "rustc_span", - "rustc_target", "smallvec 1.0.0", ] diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 50e1726240fff..3416d67f755cf 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -691,6 +691,7 @@ def build_bootstrap(self): target_linker = self.get_toml("linker", build_section) if target_linker is not None: env["RUSTFLAGS"] += " -C linker=" + target_linker + # After the next cfg(bootstrap) bump, add "-Wunused_extern_options" to RUSTFLAGS env["RUSTFLAGS"] += " -Wrust_2018_idioms -Wunused_lifetimes" if self.get_toml("deny-warnings", "rust") != "false": env["RUSTFLAGS"] += " -Dwarnings" diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index e4b57cddfb891..2a0bf7e9909d8 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1067,6 +1067,10 @@ impl<'a> Builder<'a> { // some code doesn't go through this `rustc` wrapper. rustflags.arg("-Wrust_2018_idioms"); rustflags.arg("-Wunused_lifetimes"); + // Remove this after the next cfg(bootstrap) bump + if stage != 0 { + rustflags.arg("-Wunused_extern_options"); + } if self.config.deny_warnings { rustflags.arg("-Dwarnings"); diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index ffa4176cc7969..1c340acfa84cc 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -174,3 +174,7 @@ mod std { pub mod __export { pub use core::format_args; } + +// Suppress warning: this is only used in benchmarks +#[cfg(test)] +use rand_xorshift as _; diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index ea75f8903c368..75786a319dae2 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -17,6 +17,13 @@ use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; +// Supress warning: this crate is only used in benchmarks +use rand_xorshift as _; + +// Supress warning: these crates are used indirectly +use alloc as _; +use compiler_builtins as _; + mod arc; mod binary_heap; mod boxed; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 055d70effc6e6..31f70433ecb95 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -91,3 +91,8 @@ pub mod util { // Allows macros to refer to this crate as `::rustc` extern crate self as rustc; + +// Suppress warning: these crates will be unused when cfg(parallel_compiler) is not enabled +use jobserver as _; +use rustc_rayon as _; +use rustc_rayon_core as _; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7bcd63b965534..7d21382b60eca 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -30,8 +30,8 @@ use rustc_ast::ast::{self, Ident, Name}; use rustc_ast::node_id::{NodeId, NodeMap, NodeSet}; use rustc_attr as attr; use rustc_data_structures::captures::Captures; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator}; @@ -136,6 +136,9 @@ pub struct ResolverOutputs { /// Extern prelude entries. The value is `true` if the entry was introduced /// via `extern crate` item and not `--extern` option or compiler built-in. pub extern_prelude: FxHashMap, + /// All crates that ended up getting loaded. + /// Used to determine which `--extern` entries are unused + pub used_crates: Option>, } #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)] diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 05dcc9e85ac52..548581ef7b001 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -383,7 +383,7 @@ pub trait PrettyPrinter<'tcx>: .tcx() .item_children(visible_parent) .iter() - .find(|child| child.res.def_id() == def_id) + .find(|child| child.res.opt_def_id() == Some(def_id)) .map(|child| child.ident.name); if let Some(reexport) = reexport { *name = reexport; diff --git a/src/librustc_ast_pretty/Cargo.toml b/src/librustc_ast_pretty/Cargo.toml index 82be095db8805..81d98721089f5 100644 --- a/src/librustc_ast_pretty/Cargo.toml +++ b/src/librustc_ast_pretty/Cargo.toml @@ -12,5 +12,4 @@ doctest = false [dependencies] log = "0.4" rustc_span = { path = "../librustc_span" } -rustc_data_structures = { path = "../librustc_data_structures" } rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_attr/Cargo.toml b/src/librustc_attr/Cargo.toml index 8aaba15d84ad2..a7a7e3dcc5f02 100644 --- a/src/librustc_attr/Cargo.toml +++ b/src/librustc_attr/Cargo.toml @@ -17,6 +17,5 @@ rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_macros = { path = "../librustc_macros" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_session = { path = "../librustc_session" } rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 13792a0c890c4..10287ef5c3976 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -24,6 +24,11 @@ #![feature(thread_id_value)] #![allow(rustc::default_hash_types)] +// Suppress warning: these crates will be unused when cfg(parallel_compiler) is not enabled +use crossbeam_utils as _; +use rayon as _; +use rayon_core as _; + #[macro_use] extern crate log; #[cfg(unix)] diff --git a/src/librustc_infer/Cargo.toml b/src/librustc_infer/Cargo.toml index de99214901d9b..ab2b0dcb6c7c3 100644 --- a/src/librustc_infer/Cargo.toml +++ b/src/librustc_infer/Cargo.toml @@ -17,7 +17,6 @@ rustc_attr = { path = "../librustc_attr" } rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -rustc_error_codes = { path = "../librustc_error_codes" } rustc_hir = { path = "../librustc_hir" } rustc_index = { path = "../librustc_index" } rustc_macros = { path = "../librustc_macros" } diff --git a/src/librustc_interface/lib.rs b/src/librustc_interface/lib.rs index ba1e2216ca805..dc4a3e24b4e65 100644 --- a/src/librustc_interface/lib.rs +++ b/src/librustc_interface/lib.rs @@ -21,3 +21,6 @@ pub use queries::Queries; #[cfg(test)] mod tests; + +// Suppress warning: this crate will be unused when cfg(parallel_compiler) is not enable +use rayon as _; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 29e9ea1833f8e..2f7d1c1239aa1 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -26,7 +26,7 @@ use rustc_data_structures::{box_region_allow_access, declare_box_region_type, pa use rustc_errors::PResult; use rustc_expand::base::ExtCtxt; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; -use rustc_hir::Crate; +use rustc_hir::{Crate, CRATE_HIR_ID}; use rustc_infer::traits; use rustc_lint::LintStore; use rustc_mir as mir; @@ -35,6 +35,7 @@ use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str}; use rustc_passes::{self, hir_stats, layout_test}; use rustc_plugin_impl as plugin; use rustc_resolve::{Resolver, ResolverArenas}; +use rustc_span::symbol::sym; use rustc_span::symbol::Symbol; use rustc_span::FileName; use rustc_typeck as typeck; @@ -50,6 +51,9 @@ use std::path::PathBuf; use std::rc::Rc; use std::{env, fs, iter, mem}; +use log::debug; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; + pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> { let krate = sess.time("parse_crate", || match input { Input::File(file) => parse_crate_from_file(file, &sess.parse_sess), @@ -733,6 +737,9 @@ pub fn create_global_ctxt<'tcx>( callback(sess, &mut local_providers, &mut extern_providers); } + let extern_prelude = resolver_outputs.extern_prelude.clone(); + let used_crates = resolver_outputs.used_crates.as_ref().unwrap().clone(); + let gcx = sess.time("setup_global_ctxt", || { global_ctxt.init_locking(|| { TyCtxt::create_global_ctxt( @@ -753,11 +760,60 @@ pub fn create_global_ctxt<'tcx>( // Do some initialization of the DepGraph that can only be done with the tcx available. ty::tls::enter_global(&gcx, |tcx| { tcx.sess.time("dep_graph_tcx_init", || rustc_incremental::dep_graph_tcx_init(tcx)); + check_unused_crates(tcx, &extern_prelude, &used_crates); }); QueryContext(gcx) } +fn check_unused_crates( + tcx: TyCtxt<'_>, + extern_prelude: &FxHashMap, + used_crates: &FxHashSet, +) { + for (krate, introduced_by_item) in extern_prelude { + let krate = *krate; + if *introduced_by_item { + debug!("check_unused_crate: crate {:?} added by `extern crate`, skipping", krate); + continue; + } + if used_crates.contains(&krate) { + debug!("check_unused_crate: crate {:?} was used, skipping", krate); + continue; + } + + // HACK: These should not be hardcoded. However, libstd needs + // both of them mentioned in its Cargo.tonl, and trying to + // add 'use' or 'extern crate' statements for both crates + // causes an error. + // + // If either of these crates is unused, we will never have loaded + // their metadata (otherwise, they would be used). This means that we have + // no way of checking the `panic_runtime` field in the metadata, and must + // instead rely on the crate name itself. + if krate.as_str() == "panic_abort" || krate.as_str() == "panic_unwind" { + debug!("check_unused_crate: skipping panic runtime crate {:?}", krate); + continue; + } + + if krate == sym::core || krate == sym::std { + debug!("check_unused_crate: skipping builtin crate {:?}", krate); + continue; + } + + if tcx.sess.rust_2018() && krate == sym::meta { + debug!("check_unused_crate: skipping `meta` crate"); + continue; + } + + tcx.struct_lint_node(lint::builtin::UNUSED_EXTERN_OPTIONS, CRATE_HIR_ID, |lint| { + lint.build(&format!("crate `{}` is unused in crate `{}`", krate, tcx.crate_name)) + .help(&format!("try removing `{}` from your `Cargo.toml`", krate)) + .emit(); + }); + } +} + /// Runs the resolution, type-checking, region checking and other /// miscellaneous analysis passes on the crate. fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 18b4c9ad5044c..806d7c50e6773 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -26,6 +26,7 @@ use rustc_target::spec::{PanicStrategy, TargetTriple}; use log::{debug, info, log_enabled}; use proc_macro::bridge::client::ProcMacro; +use rustc_data_structures::fx::FxHashSet; use std::path::Path; use std::{cmp, fs}; @@ -47,6 +48,7 @@ pub struct CrateLoader<'a> { local_crate_name: Symbol, // Mutable output. cstore: CStore, + loaded_crates: Option>, } pub enum LoadedMacro { @@ -197,6 +199,7 @@ impl<'a> CrateLoader<'a> { allocator_kind: None, has_global_allocator: false, }, + loaded_crates: Some(Default::default()), } } @@ -433,16 +436,23 @@ impl<'a> CrateLoader<'a> { fn resolve_crate<'b>( &'b mut self, name: Symbol, + orig_name: Option, + transitive: bool, span: Span, dep_kind: DepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, ) -> CrateNum { - self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report()) + self.maybe_resolve_crate(name, orig_name, transitive, span, dep_kind, dep) + .unwrap_or_else(|err| err.report()) } fn maybe_resolve_crate<'b>( &'b mut self, name: Symbol, + orig_name: Option, + // Whether this is a direct dependency of the current compilation session, + // or a transitive dependency + transitive: bool, span: Span, mut dep_kind: DepKind, dep: Option<(&'b CratePaths, &'b CrateDep)>, @@ -476,15 +486,33 @@ impl<'a> CrateLoader<'a> { Some(false), // is_proc_macro ); - self.load(&mut locator) + let res = self + .load(&mut locator) .map(|r| (r, None)) .or_else(|| { dep_kind = DepKind::MacrosOnly; self.load_proc_macro(&mut locator, path_kind) }) - .ok_or_else(move || LoadError::LocatorError(locator))? + .ok_or_else(move || LoadError::LocatorError(locator))?; + + res }; + // Loading a transitive dependency doesn't mark that dependency as used + // Note that we need to perform this check even when the crate was already loaded + // (e.g. `existing_match` finds the crate), since the crate may have been + // initially loaded as a transitive dependency + if !transitive { + self.loaded_crates.as_mut().unwrap().insert(name); + // If this crate was renamed via `extern crate foo as bar`, + // mark both names as loaded. An `extern crate` always forces + // the crate to be loaded, so we don't want the UNUSED_EXTERN_OPTION lint + // will never fire (though the UNUSED_EXTERN_CRATES lint might still fire) + if let Some(orig_name) = orig_name { + self.loaded_crates.as_mut().unwrap().insert(orig_name); + } + } + match result { (LoadResult::Previous(cnum), None) => { let data = self.cstore.get_crate_data(cnum); @@ -567,7 +595,7 @@ impl<'a> CrateLoader<'a> { DepKind::MacrosOnly => DepKind::MacrosOnly, _ => dep.kind, }; - self.resolve_crate(dep.name, span, dep_kind, Some((root, &dep))) + self.resolve_crate(dep.name, None, true, span, dep_kind, Some((root, &dep))) })) .collect() } @@ -662,7 +690,7 @@ impl<'a> CrateLoader<'a> { }; info!("panic runtime not found -- loading {}", name); - let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let cnum = self.resolve_crate(name, None, false, DUMMY_SP, DepKind::Implicit, None); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a panic runtime @@ -688,7 +716,7 @@ impl<'a> CrateLoader<'a> { info!("loading profiler"); let name = Symbol::intern("profiler_builtins"); - let cnum = self.resolve_crate(name, DUMMY_SP, DepKind::Implicit, None); + let cnum = self.resolve_crate(name, None, false, DUMMY_SP, DepKind::Implicit, None); let data = self.cstore.get_crate_data(cnum); // Sanity check the loaded crate to ensure it is indeed a profiler runtime @@ -830,6 +858,14 @@ impl<'a> CrateLoader<'a> { }); } + pub fn loaded_crates(&self) -> &FxHashSet { + self.loaded_crates.as_ref().unwrap() + } + + pub fn take_loaded_crates(&mut self) -> FxHashSet { + self.loaded_crates.take().unwrap() + } + pub fn postprocess(&mut self, krate: &ast::Crate) { self.inject_profiler_runtime(); self.inject_allocator_crate(krate); @@ -868,7 +904,7 @@ impl<'a> CrateLoader<'a> { DepKind::Explicit }; - let cnum = self.resolve_crate(name, item.span, dep_kind, None); + let cnum = self.resolve_crate(name, orig_name, false, item.span, dep_kind, None); let def_id = definitions.opt_local_def_id(item.id).unwrap(); let path_len = definitions.def_path(def_id.index).data.len(); @@ -888,7 +924,7 @@ impl<'a> CrateLoader<'a> { } pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> CrateNum { - let cnum = self.resolve_crate(name, span, DepKind::Explicit, None); + let cnum = self.resolve_crate(name, None, false, span, DepKind::Explicit, None); self.update_extern_crate( cnum, @@ -905,6 +941,6 @@ impl<'a> CrateLoader<'a> { } pub fn maybe_process_path_extern(&mut self, name: Symbol, span: Span) -> Option { - self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok() + self.maybe_resolve_crate(name, None, false, span, DepKind::Explicit, None).ok() } } diff --git a/src/librustc_mir_build/Cargo.toml b/src/librustc_mir_build/Cargo.toml index d53188a39e5e0..d32a847558aa1 100644 --- a/src/librustc_mir_build/Cargo.toml +++ b/src/librustc_mir_build/Cargo.toml @@ -20,7 +20,6 @@ rustc_index = { path = "../librustc_index" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } rustc_infer = { path = "../librustc_infer" } -rustc_macros = { path = "../librustc_macros" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index af8e7a5b71e46..13c6133b66545 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -14,7 +14,6 @@ rustc = { path = "../librustc" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } rustc_index = { path = "../librustc_index" } rustc_infer = { path = "../librustc_infer" } diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 11a3cedcc74e9..49f079ad27070 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -24,7 +24,6 @@ rustc_errors = { path = "../librustc_errors" } rustc_expand = { path = "../librustc_expand" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } -rustc_infer = { path = "../librustc_infer" } rustc_metadata = { path = "../librustc_metadata" } rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 492ac6ed83977..ddec3b5caa581 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1260,7 +1260,8 @@ impl<'a> Resolver<'a> { Default::default() } - pub fn into_outputs(self) -> ResolverOutputs { + pub fn into_outputs(mut self) -> ResolverOutputs { + let used_crates = self.crate_loader.take_loaded_crates(); ResolverOutputs { definitions: self.definitions, cstore: Box::new(self.crate_loader.into_cstore()), @@ -1275,6 +1276,7 @@ impl<'a> Resolver<'a> { .iter() .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), + used_crates: Some(used_crates), } } @@ -1293,6 +1295,7 @@ impl<'a> Resolver<'a> { .iter() .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), + used_crates: Some(self.crate_loader.loaded_crates().clone()), } } diff --git a/src/librustc_session/Cargo.toml b/src/librustc_session/Cargo.toml index 3895d0f8061c0..e7e7ed174e5ef 100644 --- a/src/librustc_session/Cargo.toml +++ b/src/librustc_session/Cargo.toml @@ -16,7 +16,6 @@ rustc_target = { path = "../librustc_target" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_span = { path = "../librustc_span" } -rustc_index = { path = "../librustc_index" } rustc_fs_util = { path = "../librustc_fs_util" } num_cpus = "1.0" rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs index f8a4e024605aa..be11d35989935 100644 --- a/src/librustc_session/lint/builtin.rs +++ b/src/librustc_session/lint/builtin.rs @@ -71,6 +71,12 @@ declare_lint! { "extern crates that are never used" } +declare_lint! { + pub UNUSED_EXTERN_OPTIONS, + Allow, + "extern path crates that are never used" +} + declare_lint! { pub UNUSED_QUALIFICATIONS, Allow, @@ -505,6 +511,7 @@ declare_lint_pass! { UNCONDITIONAL_PANIC, UNUSED_IMPORTS, UNUSED_EXTERN_CRATES, + UNUSED_EXTERN_OPTIONS, UNUSED_QUALIFICATIONS, UNKNOWN_LINTS, UNUSED_VARIABLES, diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index 0dc3ad2983333..d2d457d033abf 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -13,8 +13,6 @@ log = { version = "0.4" } rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_hir = { path = "../librustc_hir" } -rustc_macros = { path = "../librustc_macros" } -rustc_target = { path = "../librustc_target" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 55f9df9caafb2..85c3e044234d3 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -40,6 +40,9 @@ pub use self::types::*; pub use self::ColorConfig::*; pub use cli::TestOpts; +// Suppress warning: we need this crate in the sysroot +use proc_macro as _; + // Module to be used by rustc to compile tests in libtest pub mod test { pub use crate::{ diff --git a/src/rustc/rustc.rs b/src/rustc/rustc.rs index 6bc5aa6382c4c..c6f9a88a22010 100644 --- a/src/rustc/rustc.rs +++ b/src/rustc/rustc.rs @@ -1,3 +1,6 @@ +// Suppress warning: we need this crate in the sysroot +use rustc_codegen_ssa as _; + fn main() { // Pull in jemalloc when enabled. // diff --git a/src/test/ui/lint/auxiliary/unused_crate.rs b/src/test/ui/lint/auxiliary/unused_crate.rs new file mode 100644 index 0000000000000..78dc9bfc7000d --- /dev/null +++ b/src/test/ui/lint/auxiliary/unused_crate.rs @@ -0,0 +1 @@ +// Deliberately empty diff --git a/src/test/ui/lint/unused_extern_options.rs b/src/test/ui/lint/unused_extern_options.rs new file mode 100644 index 0000000000000..f94ee5e452f73 --- /dev/null +++ b/src/test/ui/lint/unused_extern_options.rs @@ -0,0 +1,5 @@ +// aux-crate:unused_crate=unused_crate.rs + +#![deny(unused_extern_options)] + +fn main() {} diff --git a/src/test/ui/lint/unused_extern_options.stderr b/src/test/ui/lint/unused_extern_options.stderr new file mode 100644 index 0000000000000..89fe110d50f45 --- /dev/null +++ b/src/test/ui/lint/unused_extern_options.stderr @@ -0,0 +1,11 @@ +error: crate `unused_crate` is unused in crate `unused_extern_options` + | +note: the lint level is defined here + --> $DIR/unused_extern_options.rs:3:9 + | +LL | #![deny(unused_extern_options)] + | ^^^^^^^^^^^^^^^^^^^^^ + = help: try removing `unused_crate` from your `Cargo.toml` + +error: aborting due to previous error +