Rollup merge of #72342 - jsgf:warn-unused-deps, r=petrochenkov
Warn about unused crate deps Implements #57274 by adding -Wunused-crate-dependencies. This will warn about any `--extern` option on the command line which isn't referenced by the crate source either via `use` or `extern crate`. Crates which are added for some side effect but are otherwise unreferenced - such as for symbols they define - the warning can be suppressed with `use somecrate as _;`. If a crate has multiple aliases (eg using `foo = { package = "bar" }` in `Cargo.toml`), then it will warn about each unused alias. This does not consider crate added by some other means than `--extern`, including the standard library. It also doesn't consider any crate without `add_prelude` set (though I'm not sure about this). Unfortunately this probably [does not yet work well with Cargo](https://github.com/rust-lang/rust/issues/57274#issuecomment-624839355) as it will over-specify crates, causing spurious warnings. As a result, this lint is "allow" by default and must be explicitly enabled either via `#![warn(unused_crate_deps)]` or with `-Wunused-crate-deps`.
This commit is contained in:
commit
e38fdda243
17 changed files with 188 additions and 0 deletions
|
@ -276,6 +276,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
|
|||
UNUSED_ALLOCATION,
|
||||
UNUSED_DOC_COMMENTS,
|
||||
UNUSED_EXTERN_CRATES,
|
||||
UNUSED_CRATE_DEPENDENCIES,
|
||||
UNUSED_FEATURES,
|
||||
UNUSED_LABELS,
|
||||
UNUSED_PARENS,
|
||||
|
|
|
@ -5,6 +5,7 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob
|
|||
|
||||
use rustc_ast::expand::allocator::{global_allocator_spans, AllocatorKind};
|
||||
use rustc_ast::{ast, attr};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::struct_span_err;
|
||||
|
@ -18,6 +19,7 @@ use rustc_middle::middle::cstore::{
|
|||
};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::{self, CrateType};
|
||||
use rustc_session::lint;
|
||||
use rustc_session::output::validate_crate_name;
|
||||
use rustc_session::search_paths::PathKind;
|
||||
use rustc_session::{CrateDisambiguator, Session};
|
||||
|
@ -49,6 +51,7 @@ pub struct CrateLoader<'a> {
|
|||
local_crate_name: Symbol,
|
||||
// Mutable output.
|
||||
cstore: CStore,
|
||||
used_extern_options: FxHashSet<Symbol>,
|
||||
}
|
||||
|
||||
pub enum LoadedMacro {
|
||||
|
@ -205,6 +208,7 @@ impl<'a> CrateLoader<'a> {
|
|||
allocator_kind: None,
|
||||
has_global_allocator: false,
|
||||
},
|
||||
used_extern_options: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,6 +449,9 @@ impl<'a> CrateLoader<'a> {
|
|||
dep_kind: DepKind,
|
||||
dep: Option<(&'b CratePaths, &'b CrateDep)>,
|
||||
) -> CrateNum {
|
||||
if dep.is_none() {
|
||||
self.used_extern_options.insert(name);
|
||||
}
|
||||
self.maybe_resolve_crate(name, span, dep_kind, dep).unwrap_or_else(|err| err.report())
|
||||
}
|
||||
|
||||
|
@ -839,6 +846,26 @@ impl<'a> CrateLoader<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
fn report_unused_deps(&mut self, krate: &ast::Crate) {
|
||||
// Make a point span rather than covering the whole file
|
||||
let span = krate.span.shrink_to_lo();
|
||||
// Complain about anything left over
|
||||
for (name, _) in self.sess.opts.externs.iter() {
|
||||
if !self.used_extern_options.contains(&Symbol::intern(name)) {
|
||||
self.sess.parse_sess.buffer_lint(
|
||||
lint::builtin::UNUSED_CRATE_DEPENDENCIES,
|
||||
span,
|
||||
ast::CRATE_NODE_ID,
|
||||
&format!(
|
||||
"external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`",
|
||||
name,
|
||||
self.local_crate_name,
|
||||
name),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn postprocess(&mut self, krate: &ast::Crate) {
|
||||
self.inject_profiler_runtime();
|
||||
self.inject_allocator_crate(krate);
|
||||
|
@ -847,6 +874,8 @@ impl<'a> CrateLoader<'a> {
|
|||
if log_enabled!(log::Level::Info) {
|
||||
dump_crates(&self.cstore);
|
||||
}
|
||||
|
||||
self.report_unused_deps(krate);
|
||||
}
|
||||
|
||||
pub fn process_extern_crate(
|
||||
|
|
|
@ -71,6 +71,12 @@ declare_lint! {
|
|||
"extern crates that are never used"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub UNUSED_CRATE_DEPENDENCIES,
|
||||
Allow,
|
||||
"crate dependencies that are never used"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub UNUSED_QUALIFICATIONS,
|
||||
Allow,
|
||||
|
@ -529,6 +535,7 @@ declare_lint_pass! {
|
|||
UNCONDITIONAL_PANIC,
|
||||
UNUSED_IMPORTS,
|
||||
UNUSED_EXTERN_CRATES,
|
||||
UNUSED_CRATE_DEPENDENCIES,
|
||||
UNUSED_QUALIFICATIONS,
|
||||
UNKNOWN_LINTS,
|
||||
UNUSED_VARIABLES,
|
||||
|
|
1
src/test/ui/unused-crate-deps/auxiliary/bar.rs
Normal file
1
src/test/ui/unused-crate-deps/auxiliary/bar.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub const BAR: &str = "bar";
|
5
src/test/ui/unused-crate-deps/auxiliary/foo.rs
Normal file
5
src/test/ui/unused-crate-deps/auxiliary/foo.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
// edition:2018
|
||||
// aux-crate:bar=bar.rs
|
||||
|
||||
pub const FOO: &str = "foo";
|
||||
pub use bar::BAR;
|
21
src/test/ui/unused-crate-deps/libfib.rs
Normal file
21
src/test/ui/unused-crate-deps/libfib.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Test warnings for a library crate
|
||||
|
||||
// check-pass
|
||||
// aux-crate:bar=bar.rs
|
||||
// compile-flags:--crate-type lib -Wunused-crate-dependencies
|
||||
|
||||
pub fn fib(n: u32) -> Vec<u32> {
|
||||
//~^ WARNING external crate `bar` unused in
|
||||
let mut prev = 0;
|
||||
let mut cur = 1;
|
||||
let mut v = vec![];
|
||||
|
||||
for _ in 0..n {
|
||||
v.push(prev);
|
||||
let n = prev + cur;
|
||||
prev = cur;
|
||||
cur = n;
|
||||
}
|
||||
|
||||
v
|
||||
}
|
10
src/test/ui/unused-crate-deps/libfib.stderr
Normal file
10
src/test/ui/unused-crate-deps/libfib.stderr
Normal file
|
@ -0,0 +1,10 @@
|
|||
warning: external crate `bar` unused in `libfib`: remove the dependency or add `use bar as _;`
|
||||
--> $DIR/libfib.rs:7:1
|
||||
|
|
||||
LL | pub fn fib(n: u32) -> Vec<u32> {
|
||||
| ^
|
||||
|
|
||||
= note: requested on the command line with `-W unused-crate-dependencies`
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
11
src/test/ui/unused-crate-deps/suppress.rs
Normal file
11
src/test/ui/unused-crate-deps/suppress.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Suppress by using crate
|
||||
|
||||
// edition:2018
|
||||
// check-pass
|
||||
// aux-crate:bar=bar.rs
|
||||
|
||||
#![warn(unused_crate_dependencies)]
|
||||
|
||||
use bar as _;
|
||||
|
||||
fn main() {}
|
13
src/test/ui/unused-crate-deps/unused-aliases.rs
Normal file
13
src/test/ui/unused-crate-deps/unused-aliases.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Warn about unused aliased for the crate
|
||||
|
||||
// edition:2018
|
||||
// check-pass
|
||||
// aux-crate:bar=bar.rs
|
||||
// aux-crate:barbar=bar.rs
|
||||
|
||||
#![warn(unused_crate_dependencies)]
|
||||
//~^ WARNING external crate `barbar` unused in
|
||||
|
||||
use bar as _;
|
||||
|
||||
fn main() {}
|
14
src/test/ui/unused-crate-deps/unused-aliases.stderr
Normal file
14
src/test/ui/unused-crate-deps/unused-aliases.stderr
Normal file
|
@ -0,0 +1,14 @@
|
|||
warning: external crate `barbar` unused in `unused_aliases`: remove the dependency or add `use barbar as _;`
|
||||
--> $DIR/unused-aliases.rs:8:1
|
||||
|
|
||||
LL | #![warn(unused_crate_dependencies)]
|
||||
| ^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unused-aliases.rs:8:9
|
||||
|
|
||||
LL | #![warn(unused_crate_dependencies)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
13
src/test/ui/unused-crate-deps/use_extern_crate_2015.rs
Normal file
13
src/test/ui/unused-crate-deps/use_extern_crate_2015.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Suppress by using crate
|
||||
|
||||
// edition:2015
|
||||
// check-pass
|
||||
// aux-crate:bar=bar.rs
|
||||
|
||||
#![warn(unused_crate_dependencies)]
|
||||
|
||||
extern crate bar;
|
||||
|
||||
fn main() {
|
||||
println!("bar {}", bar::BAR);
|
||||
}
|
10
src/test/ui/unused-crate-deps/warn-attr.rs
Normal file
10
src/test/ui/unused-crate-deps/warn-attr.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Check for unused crate dep, no path
|
||||
|
||||
// edition:2018
|
||||
// check-pass
|
||||
// aux-crate:bar=bar.rs
|
||||
|
||||
#![warn(unused_crate_dependencies)]
|
||||
//~^ WARNING external crate `bar` unused in
|
||||
|
||||
fn main() {}
|
14
src/test/ui/unused-crate-deps/warn-attr.stderr
Normal file
14
src/test/ui/unused-crate-deps/warn-attr.stderr
Normal file
|
@ -0,0 +1,14 @@
|
|||
warning: external crate `bar` unused in `warn_attr`: remove the dependency or add `use bar as _;`
|
||||
--> $DIR/warn-attr.rs:7:1
|
||||
|
|
||||
LL | #![warn(unused_crate_dependencies)]
|
||||
| ^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/warn-attr.rs:7:9
|
||||
|
|
||||
LL | #![warn(unused_crate_dependencies)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
10
src/test/ui/unused-crate-deps/warn-cmdline-static.rs
Normal file
10
src/test/ui/unused-crate-deps/warn-cmdline-static.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Check for unused crate dep, no path
|
||||
|
||||
// edition:2018
|
||||
// check-pass
|
||||
// compile-flags: -Wunused-crate-dependencies
|
||||
// aux-crate:bar=bar.rs
|
||||
// no-prefer-dynamic
|
||||
|
||||
fn main() {}
|
||||
//~^ WARNING external crate `bar` unused in
|
10
src/test/ui/unused-crate-deps/warn-cmdline-static.stderr
Normal file
10
src/test/ui/unused-crate-deps/warn-cmdline-static.stderr
Normal file
|
@ -0,0 +1,10 @@
|
|||
warning: external crate `bar` unused in `warn_cmdline_static`: remove the dependency or add `use bar as _;`
|
||||
--> $DIR/warn-cmdline-static.rs:9:1
|
||||
|
|
||||
LL | fn main() {}
|
||||
| ^
|
||||
|
|
||||
= note: requested on the command line with `-W unused-crate-dependencies`
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
9
src/test/ui/unused-crate-deps/warn-cmdline.rs
Normal file
9
src/test/ui/unused-crate-deps/warn-cmdline.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Check for unused crate dep, no path
|
||||
|
||||
// edition:2018
|
||||
// check-pass
|
||||
// compile-flags: -Wunused-crate-dependencies
|
||||
// aux-crate:bar=bar.rs
|
||||
|
||||
fn main() {}
|
||||
//~^ WARNING external crate `bar` unused in
|
10
src/test/ui/unused-crate-deps/warn-cmdline.stderr
Normal file
10
src/test/ui/unused-crate-deps/warn-cmdline.stderr
Normal file
|
@ -0,0 +1,10 @@
|
|||
warning: external crate `bar` unused in `warn_cmdline`: remove the dependency or add `use bar as _;`
|
||||
--> $DIR/warn-cmdline.rs:8:1
|
||||
|
|
||||
LL | fn main() {}
|
||||
| ^
|
||||
|
|
||||
= note: requested on the command line with `-W unused-crate-dependencies`
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue