diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 6503b97a1d31f..ec3b14ace4df2 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -315,21 +315,28 @@ impl Resolver<'_> { "remove the unused import" }; - let parent_module = visitor.r.get_nearest_non_block_module( - visitor.r.local_def_id(unused.use_tree_id).to_def_id(), - ); - let test_module_span = match module_to_string(parent_module) { - Some(module) - if module == "test" - || module == "tests" - || module.starts_with("test_") - || module.starts_with("tests_") - || module.ends_with("_test") - || module.ends_with("_tests") => - { - Some(parent_module.span) + // If we are in the `--test` mode, suppress a help that adds the `#[cfg(test)]` + // attribute; however, if not, suggest adding the attribute. There is no way to + // retrieve attributes here because we do not have a `TyCtxt` yet. + let test_module_span = if visitor.r.session.opts.test { + None + } else { + let parent_module = visitor.r.get_nearest_non_block_module( + visitor.r.local_def_id(unused.use_tree_id).to_def_id(), + ); + match module_to_string(parent_module) { + Some(module) + if module == "test" + || module == "tests" + || module.starts_with("test_") + || module.starts_with("tests_") + || module.ends_with("_test") + || module.ends_with("_tests") => + { + Some(parent_module.span) + } + _ => None, } - _ => None, }; visitor.r.lint_buffer.buffer_lint_with_diagnostic( diff --git a/src/test/ui/imports/unused-imports-in-test-mode.rs b/src/test/ui/imports/unused-imports-in-test-mode.rs new file mode 100644 index 0000000000000..ed0bb65b3aa91 --- /dev/null +++ b/src/test/ui/imports/unused-imports-in-test-mode.rs @@ -0,0 +1,84 @@ +// compile-flags: --test + +#![deny(unused_imports)] + +use std::io::BufRead; //~ ERROR unused import: `std::io::BufRead` + +fn a() {} +fn b() {} + +mod test { + use super::a; //~ ERROR unused import: `super::a` + + fn foo() { + use crate::b; //~ ERROR unused import: `crate::b` + } +} + +mod tests { + use super::a; //~ ERROR unused import: `super::a` + + fn foo() { + use crate::b; //~ ERROR unused import: `crate::b` + } +} + +mod test_a { + use super::a; //~ ERROR unused import: `super::a` + + fn foo() { + use crate::b; //~ ERROR unused import: `crate::b` + } +} + +mod a_test { + use super::a; //~ ERROR unused import: `super::a` + + fn foo() { + use crate::b; //~ ERROR unused import: `crate::b` + } +} + +mod tests_a { + use super::a; //~ ERROR unused import: `super::a` + + fn foo() { + use crate::b; //~ ERROR unused import: `crate::b` + } +} + +mod a_tests { + use super::a; //~ ERROR unused import: `super::a` + + fn foo() { + use crate::b; //~ ERROR unused import: `crate::b` + } +} + +mod fastest_search { + use super::a; //~ ERROR unused import: `super::a` + + fn foo() { + use crate::b; //~ ERROR unused import: `crate::b` + } +} + +#[cfg(test)] +mod test_has_attr { + use super::a; //~ ERROR unused import: `super::a` + + fn foo() { + use crate::b; //~ ERROR unused import: `crate::b` + } +} + +mod test_has_no_attr { + #[cfg(test)] + use super::a; //~ ERROR unused import: `super::a` + + fn foo() { + use crate::b; //~ ERROR unused import: `crate::b` + } +} + +fn main() {} diff --git a/src/test/ui/imports/unused-imports-in-test-mode.stderr b/src/test/ui/imports/unused-imports-in-test-mode.stderr new file mode 100644 index 0000000000000..1847abd64b4f2 --- /dev/null +++ b/src/test/ui/imports/unused-imports-in-test-mode.stderr @@ -0,0 +1,122 @@ +error: unused import: `std::io::BufRead` + --> $DIR/unused-imports-in-test-mode.rs:5:5 + | +LL | use std::io::BufRead; + | ^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-imports-in-test-mode.rs:3:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: unused import: `super::a` + --> $DIR/unused-imports-in-test-mode.rs:11:9 + | +LL | use super::a; + | ^^^^^^^^ + +error: unused import: `crate::b` + --> $DIR/unused-imports-in-test-mode.rs:14:13 + | +LL | use crate::b; + | ^^^^^^^^ + +error: unused import: `super::a` + --> $DIR/unused-imports-in-test-mode.rs:19:9 + | +LL | use super::a; + | ^^^^^^^^ + +error: unused import: `crate::b` + --> $DIR/unused-imports-in-test-mode.rs:22:13 + | +LL | use crate::b; + | ^^^^^^^^ + +error: unused import: `super::a` + --> $DIR/unused-imports-in-test-mode.rs:27:9 + | +LL | use super::a; + | ^^^^^^^^ + +error: unused import: `crate::b` + --> $DIR/unused-imports-in-test-mode.rs:30:13 + | +LL | use crate::b; + | ^^^^^^^^ + +error: unused import: `super::a` + --> $DIR/unused-imports-in-test-mode.rs:35:9 + | +LL | use super::a; + | ^^^^^^^^ + +error: unused import: `crate::b` + --> $DIR/unused-imports-in-test-mode.rs:38:13 + | +LL | use crate::b; + | ^^^^^^^^ + +error: unused import: `super::a` + --> $DIR/unused-imports-in-test-mode.rs:43:9 + | +LL | use super::a; + | ^^^^^^^^ + +error: unused import: `crate::b` + --> $DIR/unused-imports-in-test-mode.rs:46:13 + | +LL | use crate::b; + | ^^^^^^^^ + +error: unused import: `super::a` + --> $DIR/unused-imports-in-test-mode.rs:51:9 + | +LL | use super::a; + | ^^^^^^^^ + +error: unused import: `crate::b` + --> $DIR/unused-imports-in-test-mode.rs:54:13 + | +LL | use crate::b; + | ^^^^^^^^ + +error: unused import: `super::a` + --> $DIR/unused-imports-in-test-mode.rs:59:9 + | +LL | use super::a; + | ^^^^^^^^ + +error: unused import: `crate::b` + --> $DIR/unused-imports-in-test-mode.rs:62:13 + | +LL | use crate::b; + | ^^^^^^^^ + +error: unused import: `super::a` + --> $DIR/unused-imports-in-test-mode.rs:68:9 + | +LL | use super::a; + | ^^^^^^^^ + +error: unused import: `crate::b` + --> $DIR/unused-imports-in-test-mode.rs:71:13 + | +LL | use crate::b; + | ^^^^^^^^ + +error: unused import: `super::a` + --> $DIR/unused-imports-in-test-mode.rs:77:9 + | +LL | use super::a; + | ^^^^^^^^ + +error: unused import: `crate::b` + --> $DIR/unused-imports-in-test-mode.rs:80:13 + | +LL | use crate::b; + | ^^^^^^^^ + +error: aborting due to 19 previous errors +