diff --git a/tests/ui/auxiliary/wildcard_imports_helper.rs b/tests/ui/auxiliary/wildcard_imports_helper.rs
new file mode 100644
index 00000000000..414477aedd7
--- /dev/null
+++ b/tests/ui/auxiliary/wildcard_imports_helper.rs
@@ -0,0 +1,21 @@
+pub use crate::extern_exports::*;
+
+pub fn extern_foo() {}
+pub fn extern_bar() {}
+
+pub struct ExternA;
+
+pub mod inner {
+    pub mod inner_for_self_import {
+        pub fn inner_extern_foo() {}
+        pub fn inner_extern_bar() {}
+    }
+}
+
+mod extern_exports {
+    pub fn extern_exported() {}
+    pub struct ExternExportedStruct;
+    pub enum ExternExportedEnum {
+        A,
+    }
+}
diff --git a/tests/ui/wildcard_imports.fixed b/tests/ui/wildcard_imports.fixed
new file mode 100644
index 00000000000..97c8c6068e5
--- /dev/null
+++ b/tests/ui/wildcard_imports.fixed
@@ -0,0 +1,137 @@
+// run-rustfix
+// aux-build:wildcard_imports_helper.rs
+
+#![warn(clippy::wildcard_imports)]
+#![allow(unused)]
+#![warn(unused_imports)]
+
+extern crate wildcard_imports_helper;
+
+use crate::fn_mod::foo;
+use crate::mod_mod::inner_mod;
+use crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod};
+#[macro_use]
+use crate::struct_mod::{A, inner_struct_mod};
+
+#[allow(unused_imports)]
+use wildcard_imports_helper::inner::inner_for_self_import;
+use wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar;
+use wildcard_imports_helper::{ExternA, extern_foo};
+
+mod fn_mod {
+    pub fn foo() {}
+}
+
+mod mod_mod {
+    pub mod inner_mod {
+        pub fn foo() {}
+    }
+}
+
+mod multi_fn_mod {
+    pub fn multi_foo() {}
+    pub fn multi_bar() {}
+    pub fn multi_baz() {}
+    pub mod multi_inner_mod {
+        pub fn foo() {}
+    }
+}
+
+mod struct_mod {
+    pub struct A;
+    pub struct B;
+    pub mod inner_struct_mod {
+        pub struct C;
+    }
+
+    #[macro_export]
+    macro_rules! double_struct_import_test {
+        () => {
+            let _ = A;
+        };
+    }
+}
+
+fn main() {
+    foo();
+    multi_foo();
+    multi_bar();
+    multi_inner_mod::foo();
+    inner_mod::foo();
+    extern_foo();
+    inner_extern_bar();
+
+    let _ = A;
+    let _ = inner_struct_mod::C;
+    let _ = ExternA;
+
+    double_struct_import_test!();
+    double_struct_import_test!();
+}
+
+mod in_fn_test {
+    pub use self::inner_exported::*;
+    #[allow(unused_imports)]
+    pub(crate) use self::inner_exported2::*;
+
+    fn test_intern() {
+        use crate::fn_mod::foo;
+
+        foo();
+    }
+
+    fn test_extern() {
+        use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo};
+        use wildcard_imports_helper::{ExternA, extern_foo};
+
+        inner_for_self_import::inner_extern_foo();
+        inner_extern_foo();
+
+        extern_foo();
+
+        let _ = ExternA;
+    }
+
+    fn test_inner_nested() {
+        use self::{inner::inner_foo, inner2::inner_bar};
+
+        inner_foo();
+        inner_bar();
+    }
+
+    fn test_extern_reexported() {
+        use wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported};
+
+        extern_exported();
+        let _ = ExternExportedStruct;
+        let _ = ExternExportedEnum::A;
+    }
+
+    mod inner_exported {
+        pub fn exported() {}
+        pub struct ExportedStruct;
+        pub enum ExportedEnum {
+            A,
+        }
+    }
+
+    mod inner_exported2 {
+        pub(crate) fn exported2() {}
+    }
+
+    mod inner {
+        pub fn inner_foo() {}
+    }
+
+    mod inner2 {
+        pub fn inner_bar() {}
+    }
+}
+
+fn test_reexported() {
+    use crate::in_fn_test::{ExportedEnum, ExportedStruct, exported};
+
+    exported();
+    let _ = ExportedStruct;
+    let _ = ExportedEnum::A;
+}
diff --git a/tests/ui/wildcard_imports.rs b/tests/ui/wildcard_imports.rs
new file mode 100644
index 00000000000..045356672e3
--- /dev/null
+++ b/tests/ui/wildcard_imports.rs
@@ -0,0 +1,137 @@
+// run-rustfix
+// aux-build:wildcard_imports_helper.rs
+
+#![warn(clippy::wildcard_imports)]
+#![allow(unused)]
+#![warn(unused_imports)]
+
+extern crate wildcard_imports_helper;
+
+use crate::fn_mod::*;
+use crate::mod_mod::*;
+use crate::multi_fn_mod::*;
+#[macro_use]
+use crate::struct_mod::*;
+
+#[allow(unused_imports)]
+use wildcard_imports_helper::inner::inner_for_self_import;
+use wildcard_imports_helper::inner::inner_for_self_import::*;
+use wildcard_imports_helper::*;
+
+mod fn_mod {
+    pub fn foo() {}
+}
+
+mod mod_mod {
+    pub mod inner_mod {
+        pub fn foo() {}
+    }
+}
+
+mod multi_fn_mod {
+    pub fn multi_foo() {}
+    pub fn multi_bar() {}
+    pub fn multi_baz() {}
+    pub mod multi_inner_mod {
+        pub fn foo() {}
+    }
+}
+
+mod struct_mod {
+    pub struct A;
+    pub struct B;
+    pub mod inner_struct_mod {
+        pub struct C;
+    }
+
+    #[macro_export]
+    macro_rules! double_struct_import_test {
+        () => {
+            let _ = A;
+        };
+    }
+}
+
+fn main() {
+    foo();
+    multi_foo();
+    multi_bar();
+    multi_inner_mod::foo();
+    inner_mod::foo();
+    extern_foo();
+    inner_extern_bar();
+
+    let _ = A;
+    let _ = inner_struct_mod::C;
+    let _ = ExternA;
+
+    double_struct_import_test!();
+    double_struct_import_test!();
+}
+
+mod in_fn_test {
+    pub use self::inner_exported::*;
+    #[allow(unused_imports)]
+    pub(crate) use self::inner_exported2::*;
+
+    fn test_intern() {
+        use crate::fn_mod::*;
+
+        foo();
+    }
+
+    fn test_extern() {
+        use wildcard_imports_helper::inner::inner_for_self_import::{self, *};
+        use wildcard_imports_helper::*;
+
+        inner_for_self_import::inner_extern_foo();
+        inner_extern_foo();
+
+        extern_foo();
+
+        let _ = ExternA;
+    }
+
+    fn test_inner_nested() {
+        use self::{inner::*, inner2::*};
+
+        inner_foo();
+        inner_bar();
+    }
+
+    fn test_extern_reexported() {
+        use wildcard_imports_helper::*;
+
+        extern_exported();
+        let _ = ExternExportedStruct;
+        let _ = ExternExportedEnum::A;
+    }
+
+    mod inner_exported {
+        pub fn exported() {}
+        pub struct ExportedStruct;
+        pub enum ExportedEnum {
+            A,
+        }
+    }
+
+    mod inner_exported2 {
+        pub(crate) fn exported2() {}
+    }
+
+    mod inner {
+        pub fn inner_foo() {}
+    }
+
+    mod inner2 {
+        pub fn inner_bar() {}
+    }
+}
+
+fn test_reexported() {
+    use crate::in_fn_test::*;
+
+    exported();
+    let _ = ExportedStruct;
+    let _ = ExportedEnum::A;
+}
diff --git a/tests/ui/wildcard_imports.stderr b/tests/ui/wildcard_imports.stderr
new file mode 100644
index 00000000000..111481e52d0
--- /dev/null
+++ b/tests/ui/wildcard_imports.stderr
@@ -0,0 +1,82 @@
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:10:5
+   |
+LL | use crate::fn_mod::*;
+   |     ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
+   |
+   = note: `-D clippy::wildcard-imports` implied by `-D warnings`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:11:5
+   |
+LL | use crate::mod_mod::*;
+   |     ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:12:5
+   |
+LL | use crate::multi_fn_mod::*;
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:14:5
+   |
+LL | use crate::struct_mod::*;
+   |     ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:18:5
+   |
+LL | use wildcard_imports_helper::inner::inner_for_self_import::*;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:19:5
+   |
+LL | use wildcard_imports_helper::*;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:78:13
+   |
+LL |         use crate::fn_mod::*;
+   |             ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:84:75
+   |
+LL |         use wildcard_imports_helper::inner::inner_for_self_import::{self, *};
+   |                                                                           ^ help: try: `inner_extern_foo`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:85:13
+   |
+LL |         use wildcard_imports_helper::*;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:96:20
+   |
+LL |         use self::{inner::*, inner2::*};
+   |                    ^^^^^^^^ help: try: `inner::inner_foo`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:96:30
+   |
+LL |         use self::{inner::*, inner2::*};
+   |                              ^^^^^^^^^ help: try: `inner2::inner_bar`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:103:13
+   |
+LL |         use wildcard_imports_helper::*;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:132:9
+   |
+LL |     use crate::in_fn_test::*;
+   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}`
+
+error: aborting due to 13 previous errors
+