about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-04-11 14:10:34 -0400
committerMichael Goulet <michael@errs.io>2024-07-31 00:07:42 -0400
commitf6f587e7ea7ce26418fdaca7dd05faff8c68fc9d (patch)
tree6aa1cbdbd8f72f62456d1afa315faa00aa6a52a4
parent006c8df322e55c14d845e1fe317ca1445c2f8e6b (diff)
downloadrust-f6f587e7ea7ce26418fdaca7dd05faff8c68fc9d.tar.gz
rust-f6f587e7ea7ce26418fdaca7dd05faff8c68fc9d.zip
Introduce REDUNDANT_IMPORTS lint
-rw-r--r--compiler/rustc_lint/messages.ftl8
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs26
-rw-r--r--compiler/rustc_resolve/src/imports.rs8
-rw-r--r--compiler/rustc_resolve/src/lib.rs4
-rw-r--r--tests/ui/imports/redundant-import-extern-prelude.rs7
-rw-r--r--tests/ui/imports/redundant-import-extern-prelude.stderr14
-rw-r--r--tests/ui/imports/redundant-import-issue-121915-2015.rs5
-rw-r--r--tests/ui/imports/redundant-import-issue-121915-2015.stderr17
-rw-r--r--tests/ui/imports/redundant-import-lang-prelude-attr.rs7
-rw-r--r--tests/ui/imports/redundant-import-lang-prelude-attr.stderr14
-rw-r--r--tests/ui/imports/redundant-import-lang-prelude.rs7
-rw-r--r--tests/ui/imports/redundant-import-lang-prelude.stderr14
-rw-r--r--tests/ui/imports/suggest-remove-issue-121315.rs11
-rw-r--r--tests/ui/imports/suggest-remove-issue-121315.stderr52
-rw-r--r--tests/ui/lint/unused/issue-59896.rs5
-rw-r--r--tests/ui/lint/unused/issue-59896.stderr17
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-glob-parent.rs4
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-glob-parent.stderr17
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-glob.rs4
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-glob.stderr16
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-issue-71450.rs5
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-issue-71450.stderr17
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.rs14
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr44
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs8
-rw-r--r--tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr26
-rw-r--r--tests/ui/lint/use-redundant/use-redundant.rs4
-rw-r--r--tests/ui/lint/use-redundant/use-redundant.stderr19
28 files changed, 332 insertions, 62 deletions
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 987dbf6db63..7e4feb0a827 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -700,10 +700,10 @@ lint_reason_must_be_string_literal = reason must be a string literal
 lint_reason_must_come_last = reason in lint attribute must come last
 
 lint_redundant_import = the item `{$ident}` is imported redundantly
-    .label_imported_here = the item `{ident}` is already imported here
-    .label_defined_here = the item `{ident}` is already defined here
-    .label_imported_prelude = the item `{ident}` is already imported by the extern prelude
-    .label_defined_prelude = the item `{ident}` is already defined by the extern prelude
+    .label_imported_here = the item `{$ident}` is already imported here
+    .label_defined_here = the item `{$ident}` is already defined here
+    .label_imported_prelude = the item `{$ident}` is already imported by the extern prelude
+    .label_defined_prelude = the item `{$ident}` is already defined by the extern prelude
 
 lint_redundant_import_visibility = glob import doesn't reexport anything with visibility `{$import_vis}` because no imported item is public enough
     .note = the most public imported item is `{$max_vis}`
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 246b5160764..3fdfb327c70 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -82,6 +82,7 @@ declare_lint_pass! {
         PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
         PTR_CAST_ADD_AUTO_TO_OBJECT,
         PUB_USE_OF_PRIVATE_EXTERN_CRATE,
+        REDUNDANT_IMPORTS,
         REDUNDANT_LIFETIMES,
         REFINING_IMPL_TRAIT_INTERNAL,
         REFINING_IMPL_TRAIT_REACHABLE,
@@ -427,6 +428,31 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `redundant_imports` lint detects imports that are redundant due to being
+    /// imported already; either through a previous import, or being present in
+    /// the prelude.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(redundant_imports)]
+    /// use std::option::Option::None;
+    /// fn foo() -> Option<i32> { None }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Redundant imports are unnecessary and can be removed to simplify code.
+    /// If you intended to re-export the item to make it available outside of the
+    /// module, add a visibility modifier like `pub`.
+    pub REDUNDANT_IMPORTS,
+    Allow,
+    "imports that are redundant due to being imported already"
+}
+
+declare_lint! {
     /// The `must_not_suspend` lint guards against values that shouldn't be held across suspend points
     /// (`.await`)
     ///
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index f76fa62a009..0fa5cde9424 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -14,7 +14,7 @@ use rustc_middle::metadata::{ModChild, Reexport};
 use rustc_middle::{span_bug, ty};
 use rustc_session::lint::builtin::{
     AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE,
-    UNUSED_IMPORTS,
+    REDUNDANT_IMPORTS, UNUSED_IMPORTS,
 };
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -1387,14 +1387,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             let mut redundant_spans: Vec<_> = redundant_span.present_items().collect();
             redundant_spans.sort();
             redundant_spans.dedup();
-            /* FIXME(unused_imports): Add this back as a new lint
-            self.lint_buffer.buffer_lint_with_diagnostic(
-                UNUSED_IMPORTS,
+            self.lint_buffer.buffer_lint(
+                REDUNDANT_IMPORTS,
                 id,
                 import.span,
                 BuiltinLintDiag::RedundantImport(redundant_spans, source),
             );
-            */
             return true;
         }
 
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 6aca0545e64..a42083b9dea 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -178,8 +178,8 @@ enum ImplTraitContext {
 
 /// Used for tracking import use types which will be used for redundant import checking.
 /// ### Used::Scope Example
-///  ```rust,ignore (redundant_imports)
-/// #![deny(unused_imports)]
+///  ```rust,compile_fail
+/// #![deny(redundant_imports)]
 /// use std::mem::drop;
 /// fn main() {
 ///     let s = Box::new(32);
diff --git a/tests/ui/imports/redundant-import-extern-prelude.rs b/tests/ui/imports/redundant-import-extern-prelude.rs
index f1de06417aa..0064eaa9318 100644
--- a/tests/ui/imports/redundant-import-extern-prelude.rs
+++ b/tests/ui/imports/redundant-import-extern-prelude.rs
@@ -1,16 +1,17 @@
-//@ check-pass
 // Check that we detect imports that are redundant due to the extern prelude
 // and that we emit a reasonable diagnostic.
 // issue: rust-lang/rust#121915
+//~^^^ NOTE the item `aux_issue_121915` is already defined by the extern prelude
 
 // See also the discussion in <https://github.com/rust-lang/rust/pull/122954>.
 
 //@ compile-flags: --extern aux_issue_121915 --edition 2018
 //@ aux-build: aux-issue-121915.rs
 
-#[deny(unused_imports)]
+#[deny(redundant_imports)]
+//~^ NOTE the lint level is defined here
 fn main() {
     use aux_issue_121915;
-    //FIXME(unused_imports): ~^ ERROR the item `aux_issue_121915` is imported redundantly
+    //~^ ERROR the item `aux_issue_121915` is imported redundantly
     aux_issue_121915::item();
 }
diff --git a/tests/ui/imports/redundant-import-extern-prelude.stderr b/tests/ui/imports/redundant-import-extern-prelude.stderr
new file mode 100644
index 00000000000..6d2518c1284
--- /dev/null
+++ b/tests/ui/imports/redundant-import-extern-prelude.stderr
@@ -0,0 +1,14 @@
+error: the item `aux_issue_121915` is imported redundantly
+  --> $DIR/redundant-import-extern-prelude.rs:14:9
+   |
+LL |     use aux_issue_121915;
+   |         ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by the extern prelude
+   |
+note: the lint level is defined here
+  --> $DIR/redundant-import-extern-prelude.rs:11:8
+   |
+LL | #[deny(redundant_imports)]
+   |        ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/imports/redundant-import-issue-121915-2015.rs b/tests/ui/imports/redundant-import-issue-121915-2015.rs
index be3b8209ada..dc499bc40b6 100644
--- a/tests/ui/imports/redundant-import-issue-121915-2015.rs
+++ b/tests/ui/imports/redundant-import-issue-121915-2015.rs
@@ -1,12 +1,11 @@
-//@ check-pass
 //@ compile-flags: --extern aux_issue_121915 --edition 2015
 //@ aux-build: aux-issue-121915.rs
 
 extern crate aux_issue_121915;
 
-#[deny(unused_imports)]
+#[deny(redundant_imports)]
 fn main() {
     use aux_issue_121915;
-    //FIXME(unused_imports): ~^ ERROR the item `aux_issue_121915` is imported redundantly
+    //~^ ERROR the item `aux_issue_121915` is imported redundantly
     aux_issue_121915::item();
 }
diff --git a/tests/ui/imports/redundant-import-issue-121915-2015.stderr b/tests/ui/imports/redundant-import-issue-121915-2015.stderr
new file mode 100644
index 00000000000..f4e9f604896
--- /dev/null
+++ b/tests/ui/imports/redundant-import-issue-121915-2015.stderr
@@ -0,0 +1,17 @@
+error: the item `aux_issue_121915` is imported redundantly
+  --> $DIR/redundant-import-issue-121915-2015.rs:8:9
+   |
+LL | extern crate aux_issue_121915;
+   | ------------------------------ the item `aux_issue_121915` is already imported here
+...
+LL |     use aux_issue_121915;
+   |         ^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/redundant-import-issue-121915-2015.rs:6:8
+   |
+LL | #[deny(redundant_imports)]
+   |        ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/imports/redundant-import-lang-prelude-attr.rs b/tests/ui/imports/redundant-import-lang-prelude-attr.rs
index 59cd570f44c..f7ee91880ba 100644
--- a/tests/ui/imports/redundant-import-lang-prelude-attr.rs
+++ b/tests/ui/imports/redundant-import-lang-prelude-attr.rs
@@ -1,6 +1,6 @@
-//@ check-pass
 // Check that we detect imports (of built-in attributes) that are redundant due to
 // the language prelude and that we emit a reasonable diagnostic.
+//~^^ NOTE the item `allow` is already defined by the extern prelude
 
 // Note that we use the term "extern prelude" in the label even though "language prelude"
 // would be more correct. However, it's not worth special-casing this.
@@ -9,9 +9,10 @@
 
 //@ edition: 2018
 
-#![deny(unused_imports)]
+#![deny(redundant_imports)]
+//~^ NOTE the lint level is defined here
 
-use allow; //FIXME(unused_imports): ~ ERROR the item `allow` is imported redundantly
+use allow; //~ ERROR the item `allow` is imported redundantly
 
 #[allow(unused)]
 fn main() {}
diff --git a/tests/ui/imports/redundant-import-lang-prelude-attr.stderr b/tests/ui/imports/redundant-import-lang-prelude-attr.stderr
new file mode 100644
index 00000000000..f0016f5fab4
--- /dev/null
+++ b/tests/ui/imports/redundant-import-lang-prelude-attr.stderr
@@ -0,0 +1,14 @@
+error: the item `allow` is imported redundantly
+  --> $DIR/redundant-import-lang-prelude-attr.rs:15:5
+   |
+LL | use allow;
+   |     ^^^^^ the item `allow` is already defined by the extern prelude
+   |
+note: the lint level is defined here
+  --> $DIR/redundant-import-lang-prelude-attr.rs:12:9
+   |
+LL | #![deny(redundant_imports)]
+   |         ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/imports/redundant-import-lang-prelude.rs b/tests/ui/imports/redundant-import-lang-prelude.rs
index 53d3b709963..3f95ffbe02e 100644
--- a/tests/ui/imports/redundant-import-lang-prelude.rs
+++ b/tests/ui/imports/redundant-import-lang-prelude.rs
@@ -1,16 +1,17 @@
-//@ check-pass
 // Check that we detect imports that are redundant due to the language prelude
 // and that we emit a reasonable diagnostic.
+//~^^ NOTE the item `u8` is already defined by the extern prelude
 
 // Note that we use the term "extern prelude" in the label even though "language prelude"
 // would be more correct. However, it's not worth special-casing this.
 
 // See also the discussion in <https://github.com/rust-lang/rust/pull/122954>.
 
-#![deny(unused_imports)]
+#![deny(redundant_imports)]
+//~^ NOTE the lint level is defined here
 
 use std::primitive::u8;
-//FIXME(unused_imports): ~^ ERROR the item `u8` is imported redundantly
+//~^ ERROR the item `u8` is imported redundantly
 
 const _: u8 = 0;
 
diff --git a/tests/ui/imports/redundant-import-lang-prelude.stderr b/tests/ui/imports/redundant-import-lang-prelude.stderr
new file mode 100644
index 00000000000..4fd57639781
--- /dev/null
+++ b/tests/ui/imports/redundant-import-lang-prelude.stderr
@@ -0,0 +1,14 @@
+error: the item `u8` is imported redundantly
+  --> $DIR/redundant-import-lang-prelude.rs:13:5
+   |
+LL | use std::primitive::u8;
+   |     ^^^^^^^^^^^^^^^^^^ the item `u8` is already defined by the extern prelude
+   |
+note: the lint level is defined here
+  --> $DIR/redundant-import-lang-prelude.rs:10:9
+   |
+LL | #![deny(redundant_imports)]
+   |         ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/imports/suggest-remove-issue-121315.rs b/tests/ui/imports/suggest-remove-issue-121315.rs
index 2bb82833a5b..ee3ceb6e3a3 100644
--- a/tests/ui/imports/suggest-remove-issue-121315.rs
+++ b/tests/ui/imports/suggest-remove-issue-121315.rs
@@ -1,20 +1,19 @@
 //@ compile-flags: --edition 2021
-
-#![deny(unused_imports)]
+#![deny(unused_imports, redundant_imports)]
 #![allow(dead_code)]
 
 fn test0() {
     // Test remove FlatUnused
     use std::convert::TryFrom;
-    //FIXME(unused_imports): ~^ ERROR the item `TryFrom` is imported redundantly
+    //~^ ERROR the item `TryFrom` is imported redundantly
     let _ = u32::try_from(5i32);
 }
 
 fn test1() {
     // FIXME(yukang) Test remove NestedFullUnused
     use std::convert::{TryFrom, TryInto};
-    //FIXME(unused_imports): ~^ ERROR the item `TryFrom` is imported redundantly
-    //FIXME(unused_imports): ~| ERROR the item `TryInto` is imported redundantly
+    //~^ ERROR the item `TryFrom` is imported redundantly
+    //~| ERROR the item `TryInto` is imported redundantly
 
     let _ = u32::try_from(5i32);
     let _a: i32 = u32::try_into(5u32).unwrap();
@@ -24,7 +23,7 @@ fn test2() {
     // FIXME(yukang): Test remove both redundant and unused
     use std::convert::{AsMut, Into};
     //~^ ERROR unused import: `AsMut`
-    //FIXME(unused_imports): ~| ERROR the item `Into` is imported redundantly
+    //~| ERROR the item `Into` is imported redundantly
 
     let _a: u32 = (5u8).into();
 }
diff --git a/tests/ui/imports/suggest-remove-issue-121315.stderr b/tests/ui/imports/suggest-remove-issue-121315.stderr
index 5701514e1bd..5d0bf9bea6a 100644
--- a/tests/ui/imports/suggest-remove-issue-121315.stderr
+++ b/tests/ui/imports/suggest-remove-issue-121315.stderr
@@ -1,20 +1,62 @@
+error: the item `TryFrom` is imported redundantly
+  --> $DIR/suggest-remove-issue-121315.rs:7:9
+   |
+LL |     use std::convert::TryFrom;
+   |         ^^^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `TryFrom` is already defined here
+   |
+note: the lint level is defined here
+  --> $DIR/suggest-remove-issue-121315.rs:2:25
+   |
+LL | #![deny(unused_imports, redundant_imports)]
+   |                         ^^^^^^^^^^^^^^^^^
+
+error: the item `TryFrom` is imported redundantly
+  --> $DIR/suggest-remove-issue-121315.rs:14:24
+   |
+LL |     use std::convert::{TryFrom, TryInto};
+   |                        ^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `TryFrom` is already defined here
+
+error: the item `TryInto` is imported redundantly
+  --> $DIR/suggest-remove-issue-121315.rs:14:33
+   |
+LL |     use std::convert::{TryFrom, TryInto};
+   |                                 ^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `TryInto` is already defined here
+
 error: unused import: `AsMut`
-  --> $DIR/suggest-remove-issue-121315.rs:25:24
+  --> $DIR/suggest-remove-issue-121315.rs:24:24
    |
 LL |     use std::convert::{AsMut, Into};
    |                        ^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/suggest-remove-issue-121315.rs:3:9
+  --> $DIR/suggest-remove-issue-121315.rs:2:9
    |
-LL | #![deny(unused_imports)]
+LL | #![deny(unused_imports, redundant_imports)]
    |         ^^^^^^^^^^^^^^
 
+error: the item `Into` is imported redundantly
+  --> $DIR/suggest-remove-issue-121315.rs:24:31
+   |
+LL |     use std::convert::{AsMut, Into};
+   |                               ^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `Into` is already defined here
+
 error: unused import: `From`
-  --> $DIR/suggest-remove-issue-121315.rs:34:24
+  --> $DIR/suggest-remove-issue-121315.rs:33:24
    |
 LL |     use std::convert::{From, Infallible};
    |                        ^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/tests/ui/lint/unused/issue-59896.rs b/tests/ui/lint/unused/issue-59896.rs
index a98017524f5..5624e7f02fb 100644
--- a/tests/ui/lint/unused/issue-59896.rs
+++ b/tests/ui/lint/unused/issue-59896.rs
@@ -1,10 +1,9 @@
-//@ check-pass
-#![deny(unused_imports)]
+#![deny(redundant_imports)]
 
 struct S;
 
 fn main() {
-    use S;  //FIXME(unused_imports): ~ ERROR the item `S` is imported redundantly
+    use S;  //~ ERROR the item `S` is imported redundantly
 
     let _s = S;
 }
diff --git a/tests/ui/lint/unused/issue-59896.stderr b/tests/ui/lint/unused/issue-59896.stderr
new file mode 100644
index 00000000000..363a6419d9c
--- /dev/null
+++ b/tests/ui/lint/unused/issue-59896.stderr
@@ -0,0 +1,17 @@
+error: the item `S` is imported redundantly
+  --> $DIR/issue-59896.rs:6:9
+   |
+LL | struct S;
+   | --------- the item `S` is already defined here
+...
+LL |     use S;
+   |         ^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-59896.rs:1:9
+   |
+LL | #![deny(redundant_imports)]
+   |         ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/use-redundant/use-redundant-glob-parent.rs b/tests/ui/lint/use-redundant/use-redundant-glob-parent.rs
index 797e57f48e9..c8c413dccd3 100644
--- a/tests/ui/lint/use-redundant/use-redundant-glob-parent.rs
+++ b/tests/ui/lint/use-redundant/use-redundant-glob-parent.rs
@@ -1,5 +1,5 @@
 //@ check-pass
-#![warn(unused_imports)]
+#![warn(redundant_imports)]
 
 pub mod bar {
     pub struct Foo(pub Bar);
@@ -9,7 +9,7 @@ pub mod bar {
 use bar::*;
 
 pub fn warning() -> Foo {
-    use bar::Foo; //FIXME(unused_imports): ~ WARNING imported redundantly
+    use bar::Foo; //~ WARNING imported redundantly
     Foo(Bar('a'))
 }
 
diff --git a/tests/ui/lint/use-redundant/use-redundant-glob-parent.stderr b/tests/ui/lint/use-redundant/use-redundant-glob-parent.stderr
new file mode 100644
index 00000000000..3b06b2df674
--- /dev/null
+++ b/tests/ui/lint/use-redundant/use-redundant-glob-parent.stderr
@@ -0,0 +1,17 @@
+warning: the item `Foo` is imported redundantly
+  --> $DIR/use-redundant-glob-parent.rs:12:9
+   |
+LL | use bar::*;
+   |     ------ the item `Foo` is already imported here
+...
+LL |     use bar::Foo;
+   |         ^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/use-redundant-glob-parent.rs:2:9
+   |
+LL | #![warn(redundant_imports)]
+   |         ^^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/use-redundant/use-redundant-glob.rs b/tests/ui/lint/use-redundant/use-redundant-glob.rs
index e5835be89d8..52383d4ceff 100644
--- a/tests/ui/lint/use-redundant/use-redundant-glob.rs
+++ b/tests/ui/lint/use-redundant/use-redundant-glob.rs
@@ -1,5 +1,5 @@
 //@ check-pass
-#![warn(unused_imports)]
+#![warn(redundant_imports)]
 
 pub mod bar {
     pub struct Foo(pub Bar);
@@ -8,7 +8,7 @@ pub mod bar {
 
 pub fn warning() -> bar::Foo {
     use bar::*;
-    use bar::Foo; //FIXME(unused_imports): ~ WARNING imported redundantly
+    use bar::Foo; //~ WARNING imported redundantly
     Foo(Bar('a'))
 }
 
diff --git a/tests/ui/lint/use-redundant/use-redundant-glob.stderr b/tests/ui/lint/use-redundant/use-redundant-glob.stderr
new file mode 100644
index 00000000000..47b2ce54bb7
--- /dev/null
+++ b/tests/ui/lint/use-redundant/use-redundant-glob.stderr
@@ -0,0 +1,16 @@
+warning: the item `Foo` is imported redundantly
+  --> $DIR/use-redundant-glob.rs:11:9
+   |
+LL |     use bar::*;
+   |         ------ the item `Foo` is already imported here
+LL |     use bar::Foo;
+   |         ^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/use-redundant-glob.rs:2:9
+   |
+LL | #![warn(redundant_imports)]
+   |         ^^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/use-redundant/use-redundant-issue-71450.rs b/tests/ui/lint/use-redundant/use-redundant-issue-71450.rs
index 2db3435d46d..6a3ffa4522a 100644
--- a/tests/ui/lint/use-redundant/use-redundant-issue-71450.rs
+++ b/tests/ui/lint/use-redundant/use-redundant-issue-71450.rs
@@ -1,6 +1,6 @@
 //@ check-pass
 
-#![warn(unused_imports)]
+#![warn(redundant_imports)]
 
 mod foo {
     use std::fmt;
@@ -23,8 +23,7 @@ mod foo {
 fn main() {
 
     {
-        use std::string::String;
-        //FIXME(unused_imports): ~^ WARNING the item `String` is imported redundantly
+        use std::string::String; //~ WARNING the item `String` is imported redundantly
         // 'String' from 'std::string::String'.
         let s = String::new();
         println!("{}", s);
diff --git a/tests/ui/lint/use-redundant/use-redundant-issue-71450.stderr b/tests/ui/lint/use-redundant/use-redundant-issue-71450.stderr
new file mode 100644
index 00000000000..c14ab9e11e0
--- /dev/null
+++ b/tests/ui/lint/use-redundant/use-redundant-issue-71450.stderr
@@ -0,0 +1,17 @@
+warning: the item `String` is imported redundantly
+  --> $DIR/use-redundant-issue-71450.rs:26:13
+   |
+LL |         use std::string::String;
+   |             ^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `String` is already defined here
+   |
+note: the lint level is defined here
+  --> $DIR/use-redundant-issue-71450.rs:3:9
+   |
+LL | #![warn(redundant_imports)]
+   |         ^^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.rs b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.rs
index 62f50c8a0df..6abe3602abe 100644
--- a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.rs
+++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.rs
@@ -1,16 +1,12 @@
 //@ check-pass
-#![warn(unused_imports)]
+#![warn(redundant_imports)]
 
 
-use std::option::Option::Some;
-//FIXME(unused_imports): ~^ WARNING the item `Some` is imported redundantly
-use std::option::Option::None;
-//FIXME(unused_imports): ~ WARNING the item `None` is imported redundantly
+use std::option::Option::Some;//~ WARNING the item `Some` is imported redundantly
+use std::option::Option::None; //~ WARNING the item `None` is imported redundantly
 
-use std::result::Result::Ok;
-//FIXME(unused_imports): ~^ WARNING the item `Ok` is imported redundantly
-use std::result::Result::Err;
-//FIXME(unused_imports): ~^ WARNING the item `Err` is imported redundantly
+use std::result::Result::Ok;//~ WARNING the item `Ok` is imported redundantly
+use std::result::Result::Err;//~ WARNING the item `Err` is imported redundantly
 use std::convert::{TryFrom, TryInto};
 
 fn main() {
diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr
new file mode 100644
index 00000000000..2b0e16a87dc
--- /dev/null
+++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2015.stderr
@@ -0,0 +1,44 @@
+warning: the item `Some` is imported redundantly
+  --> $DIR/use-redundant-prelude-rust-2015.rs:5:5
+   |
+LL | use std::option::Option::Some;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `Some` is already defined here
+   |
+note: the lint level is defined here
+  --> $DIR/use-redundant-prelude-rust-2015.rs:2:9
+   |
+LL | #![warn(redundant_imports)]
+   |         ^^^^^^^^^^^^^^^^^
+
+warning: the item `None` is imported redundantly
+  --> $DIR/use-redundant-prelude-rust-2015.rs:6:5
+   |
+LL | use std::option::Option::None;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `None` is already defined here
+
+warning: the item `Ok` is imported redundantly
+  --> $DIR/use-redundant-prelude-rust-2015.rs:8:5
+   |
+LL | use std::result::Result::Ok;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `Ok` is already defined here
+
+warning: the item `Err` is imported redundantly
+  --> $DIR/use-redundant-prelude-rust-2015.rs:9:5
+   |
+LL | use std::result::Result::Err;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `Err` is already defined here
+
+warning: 4 warnings emitted
+
diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs
index 1baa1ac1b8c..236ee032b67 100644
--- a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs
+++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs
@@ -1,11 +1,9 @@
 //@ check-pass
 //@ edition:2021
-#![warn(unused_imports)]
+#![warn(redundant_imports)]
 
-use std::convert::TryFrom;
-//FIXME(unused_imports): ~^ WARNING the item `TryFrom` is imported redundantly
-use std::convert::TryInto;
-//FIXME(unused_imports): ~^ WARNING the item `TryInto` is imported redundantly
+use std::convert::TryFrom;//~ WARNING the item `TryFrom` is imported redundantly
+use std::convert::TryInto;//~ WARNING the item `TryInto` is imported redundantly
 
 fn main() {
     let _e: Result<i32, _> = 8u8.try_into();
diff --git a/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr
new file mode 100644
index 00000000000..526771c597a
--- /dev/null
+++ b/tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.stderr
@@ -0,0 +1,26 @@
+warning: the item `TryFrom` is imported redundantly
+  --> $DIR/use-redundant-prelude-rust-2021.rs:5:5
+   |
+LL | use std::convert::TryFrom;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `TryFrom` is already defined here
+   |
+note: the lint level is defined here
+  --> $DIR/use-redundant-prelude-rust-2021.rs:3:9
+   |
+LL | #![warn(redundant_imports)]
+   |         ^^^^^^^^^^^^^^^^^
+
+warning: the item `TryInto` is imported redundantly
+  --> $DIR/use-redundant-prelude-rust-2021.rs:6:5
+   |
+LL | use std::convert::TryInto;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `TryInto` is already defined here
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/use-redundant/use-redundant.rs b/tests/ui/lint/use-redundant/use-redundant.rs
index 9e4902af34b..0efed378f98 100644
--- a/tests/ui/lint/use-redundant/use-redundant.rs
+++ b/tests/ui/lint/use-redundant/use-redundant.rs
@@ -1,5 +1,5 @@
 //@ check-pass
-#![warn(unused_imports)]
+#![warn(unused_imports, redundant_imports)]
 
 use crate::foo::Bar;
 
@@ -18,7 +18,7 @@ use m1::*; //~ WARNING unused import
 use m2::*; //~ WARNING unused import
 
 fn main() {
-    use crate::foo::Bar; //FIXME(unused_imports): ~ WARNING imported redundantly
+    use crate::foo::Bar; //~ WARNING imported redundantly
     let _a: Bar = 3;
     baz();
 
diff --git a/tests/ui/lint/use-redundant/use-redundant.stderr b/tests/ui/lint/use-redundant/use-redundant.stderr
index 224e8411237..76846a1dca9 100644
--- a/tests/ui/lint/use-redundant/use-redundant.stderr
+++ b/tests/ui/lint/use-redundant/use-redundant.stderr
@@ -7,7 +7,7 @@ LL | use m1::*;
 note: the lint level is defined here
   --> $DIR/use-redundant.rs:2:9
    |
-LL | #![warn(unused_imports)]
+LL | #![warn(unused_imports, redundant_imports)]
    |         ^^^^^^^^^^^^^^
 
 warning: unused import: `m2::*`
@@ -16,5 +16,20 @@ warning: unused import: `m2::*`
 LL | use m2::*;
    |     ^^^^^
 
-warning: 2 warnings emitted
+warning: the item `Bar` is imported redundantly
+  --> $DIR/use-redundant.rs:21:9
+   |
+LL | use crate::foo::Bar;
+   |     --------------- the item `Bar` is already imported here
+...
+LL |     use crate::foo::Bar;
+   |         ^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/use-redundant.rs:2:25
+   |
+LL | #![warn(unused_imports, redundant_imports)]
+   |                         ^^^^^^^^^^^^^^^^^
+
+warning: 3 warnings emitted