diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 5361af98f3c..b1dcca46055 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1325,11 +1325,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             })
         }
 
-        // If only some candidates are accessible, take just them
-        if !candidates.iter().all(|v: &ImportSuggestion| !v.accessible) {
-            candidates.retain(|x| x.accessible)
-        }
-
         candidates
     }
 
@@ -1794,7 +1789,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 &import_suggestions,
                 Instead::Yes,
                 FoundUse::Yes,
-                DiagMode::Import { append: single_nested },
+                DiagMode::Import { append: single_nested, unresolved_import: false },
                 vec![],
                 "",
             );
@@ -2751,6 +2746,8 @@ pub(crate) enum DiagMode {
     Pattern,
     /// The binding is part of a use statement
     Import {
+        /// `true` means diagnostics is for unresolved import
+        unresolved_import: bool,
         /// `true` mean add the tips afterward for case `use a::{b,c}`,
         /// rather than replacing within.
         append: bool,
@@ -2801,6 +2798,7 @@ fn show_candidates(
         return false;
     }
 
+    let mut showed = false;
     let mut accessible_path_strings: Vec<PathString<'_>> = Vec::new();
     let mut inaccessible_path_strings: Vec<PathString<'_>> = Vec::new();
 
@@ -2959,8 +2957,11 @@ fn show_candidates(
             append_candidates(&mut msg, accessible_path_strings);
             err.help(msg);
         }
-        true
-    } else if !(inaccessible_path_strings.is_empty() || matches!(mode, DiagMode::Import { .. })) {
+        showed = true;
+    }
+    if !inaccessible_path_strings.is_empty()
+        && (!matches!(mode, DiagMode::Import { unresolved_import: false, .. }))
+    {
         let prefix =
             if let DiagMode::Pattern = mode { "you might have meant to match on " } else { "" };
         if let [(name, descr, source_span, note, _)] = &inaccessible_path_strings[..] {
@@ -3023,10 +3024,9 @@ fn show_candidates(
 
             err.span_note(multi_span, msg);
         }
-        true
-    } else {
-        false
+        showed = true;
     }
+    showed
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 89b9a074351..b38503e07b1 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -734,7 +734,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         &mut diag,
                         Some(err.span),
                         candidates,
-                        DiagMode::Import { append: false },
+                        DiagMode::Import { append: false, unresolved_import: true },
                         (source != target)
                             .then(|| format!(" as {target}"))
                             .as_deref()
diff --git a/tests/ui/imports/glob-resolve1.stderr b/tests/ui/imports/glob-resolve1.stderr
index 75e65681c3a..23b0db0fa46 100644
--- a/tests/ui/imports/glob-resolve1.stderr
+++ b/tests/ui/imports/glob-resolve1.stderr
@@ -58,6 +58,11 @@ error[E0425]: cannot find function `import` in this scope
 LL |     import();
    |     ^^^^^^ not found in this scope
    |
+note: function `bar::import` exists but is inaccessible
+  --> $DIR/glob-resolve1.rs:7:5
+   |
+LL |     fn fpriv() {}
+   |     ^^^^^^^^^^ not accessible
 help: consider importing this function
    |
 LL + use other::import;
diff --git a/tests/ui/imports/issue-4366-2.stderr b/tests/ui/imports/issue-4366-2.stderr
index 412423f4d59..b1c0092b05d 100644
--- a/tests/ui/imports/issue-4366-2.stderr
+++ b/tests/ui/imports/issue-4366-2.stderr
@@ -16,6 +16,11 @@ error[E0423]: expected function, found module `foo`
 LL |     foo();
    |     ^^^ not a function
    |
+note: function `m1::foo` exists but is inaccessible
+  --> $DIR/issue-4366-2.rs:21:5
+   |
+LL |     fn foo() {}
+   |     ^^^^^^^^ not accessible
 help: consider importing this function instead
    |
 LL + use foo::foo;
diff --git a/tests/ui/imports/issue-4366.stderr b/tests/ui/imports/issue-4366.stderr
index e63399d554e..54b7f31b231 100644
--- a/tests/ui/imports/issue-4366.stderr
+++ b/tests/ui/imports/issue-4366.stderr
@@ -4,6 +4,11 @@ error[E0425]: cannot find function `foo` in this scope
 LL |         fn sub() -> isize { foo(); 1 }
    |                             ^^^ not found in this scope
    |
+note: function `m1::foo` exists but is inaccessible
+  --> $DIR/issue-4366.rs:23:5
+   |
+LL |     fn foo() {}
+   |     ^^^^^^^^ not accessible
 help: consider importing this function
    |
 LL +         use foo::foo;
diff --git a/tests/ui/imports/show-private-items-issue-138626.rs b/tests/ui/imports/show-private-items-issue-138626.rs
new file mode 100644
index 00000000000..d9708fc33c2
--- /dev/null
+++ b/tests/ui/imports/show-private-items-issue-138626.rs
@@ -0,0 +1,19 @@
+pub mod one {
+    mod foo {
+        pub struct Foo;
+    }
+
+    pub use self::foo::Foo;
+}
+
+pub mod two {
+    mod foo {
+        mod bar {
+            pub struct Foo;
+        }
+    }
+
+    pub use crate::two::foo::Foo; //~ ERROR unresolved import `crate::two::foo::Foo` [E0432]
+}
+
+fn main() {}
diff --git a/tests/ui/imports/show-private-items-issue-138626.stderr b/tests/ui/imports/show-private-items-issue-138626.stderr
new file mode 100644
index 00000000000..b664462daed
--- /dev/null
+++ b/tests/ui/imports/show-private-items-issue-138626.stderr
@@ -0,0 +1,20 @@
+error[E0432]: unresolved import `crate::two::foo::Foo`
+  --> $DIR/show-private-items-issue-138626.rs:16:13
+   |
+LL |     pub use crate::two::foo::Foo;
+   |             ^^^^^^^^^^^^^^^^^^^^ no `Foo` in `two::foo`
+   |
+note: struct `two::foo::bar::Foo` exists but is inaccessible
+  --> $DIR/show-private-items-issue-138626.rs:12:13
+   |
+LL |             pub struct Foo;
+   |             ^^^^^^^^^^^^^^^ not accessible
+help: consider importing this struct through its public re-export instead
+   |
+LL -     pub use crate::two::foo::Foo;
+LL +     pub use one::Foo;
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0432`.
diff --git a/tests/ui/privacy/privacy-ns1.stderr b/tests/ui/privacy/privacy-ns1.stderr
index 3396330c993..c782c67e71c 100644
--- a/tests/ui/privacy/privacy-ns1.stderr
+++ b/tests/ui/privacy/privacy-ns1.stderr
@@ -7,6 +7,14 @@ LL |     pub struct Baz;
 LL |     Bar();
    |     ^^^
    |
+note: these functions exist but are inaccessible
+  --> $DIR/privacy-ns1.rs:14:5
+   |
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo1::Bar`: not accessible
+...
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo3::Bar`: not accessible
 help: a unit struct with a similar name exists
    |
 LL -     Bar();
@@ -26,6 +34,14 @@ LL |     pub struct Baz;
 LL |     Bar();
    |     ^^^
    |
+note: these functions exist but are inaccessible
+  --> $DIR/privacy-ns1.rs:14:5
+   |
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo1::Bar`: not accessible
+...
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo3::Bar`: not accessible
 help: a unit struct with a similar name exists
    |
 LL -     Bar();
@@ -45,6 +61,14 @@ LL |     pub struct Baz;
 LL |     let _x: Box<Bar>;
    |                 ^^^
    |
+note: these traits exist but are inaccessible
+  --> $DIR/privacy-ns1.rs:25:5
+   |
+LL |     trait Bar {
+   |     ^^^^^^^^^ `foo2::Bar`: not accessible
+...
+LL |     trait Bar {
+   |     ^^^^^^^^^ `foo3::Bar`: not accessible
 help: a struct with a similar name exists
    |
 LL -     let _x: Box<Bar>;
diff --git a/tests/ui/privacy/privacy-ns2.stderr b/tests/ui/privacy/privacy-ns2.stderr
index ac98682b2b3..fe1f0c9bd48 100644
--- a/tests/ui/privacy/privacy-ns2.stderr
+++ b/tests/ui/privacy/privacy-ns2.stderr
@@ -4,6 +4,14 @@ error[E0423]: expected function, tuple struct or tuple variant, found trait `Bar
 LL |     Bar();
    |     ^^^ not a function, tuple struct or tuple variant
    |
+note: these functions exist but are inaccessible
+  --> $DIR/privacy-ns2.rs:14:5
+   |
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo1::Bar`: not accessible
+...
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo3::Bar`: not accessible
 help: consider importing this function instead
    |
 LL + use foo2::Bar;
@@ -18,6 +26,14 @@ LL |     pub struct Baz;
 LL |     Bar();
    |     ^^^
    |
+note: these functions exist but are inaccessible
+  --> $DIR/privacy-ns2.rs:14:5
+   |
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo1::Bar`: not accessible
+...
+LL |     fn Bar() { }
+   |     ^^^^^^^^ `foo3::Bar`: not accessible
 help: a unit struct with a similar name exists
    |
 LL -     Bar();
@@ -34,6 +50,14 @@ error[E0573]: expected type, found function `Bar`
 LL |     let _x : Bar();
    |              ^^^^^ not a type
    |
+note: these traits exist but are inaccessible
+  --> $DIR/privacy-ns2.rs:31:5
+   |
+LL |     trait Bar {
+   |     ^^^^^^^^^ `foo2::Bar`: not accessible
+...
+LL |     trait Bar {
+   |     ^^^^^^^^^ `foo3::Bar`: not accessible
 help: use `=` if you meant to assign
    |
 LL -     let _x : Bar();
diff --git a/tests/ui/resolve/issue-21221-1.stderr b/tests/ui/resolve/issue-21221-1.stderr
index ccf03afaa19..dafa41bf312 100644
--- a/tests/ui/resolve/issue-21221-1.stderr
+++ b/tests/ui/resolve/issue-21221-1.stderr
@@ -19,6 +19,17 @@ error[E0412]: cannot find type `Mul` in this scope
 LL | fn getMul() -> Mul {
    |                ^^^ not found in this scope
    |
+note: these items exist but are inaccessible
+  --> $DIR/issue-21221-1.rs:10:5
+   |
+LL |     enum Mul {
+   |     ^^^^^^^^ `mul3::Mul`: not accessible
+...
+LL |     type Mul = String;
+   |     ^^^^^^^^^^^^^^^^^^ `mul4::Mul`: not accessible
+...
+LL |     struct Mul{
+   |     ^^^^^^^^^^ `mul5::Mul`: not accessible
 help: consider importing one of these traits
    |
 LL + use std::ops::Mul;
diff --git a/tests/ui/unresolved/unresolved-import.rs b/tests/ui/unresolved/unresolved-import.rs
index 763e9496734..b0fdcf97015 100644
--- a/tests/ui/unresolved/unresolved-import.rs
+++ b/tests/ui/unresolved/unresolved-import.rs
@@ -31,6 +31,8 @@ mod food {
 
     mod zug {
         pub mod baz {
+        //~^ NOTE module `food::zug::baz` exists but is inaccessible
+        //~| NOTE not accessible
             pub struct Foobar;
         }
     }
diff --git a/tests/ui/unresolved/unresolved-import.stderr b/tests/ui/unresolved/unresolved-import.stderr
index c65fe841001..4001695459a 100644
--- a/tests/ui/unresolved/unresolved-import.stderr
+++ b/tests/ui/unresolved/unresolved-import.stderr
@@ -26,6 +26,12 @@ LL | use food::baz;
    |     |     |
    |     |     help: a similar name exists in the module: `bag`
    |     no `baz` in `food`
+   |
+note: module `food::zug::baz` exists but is inaccessible
+  --> $DIR/unresolved-import.rs:33:9
+   |
+LL |         pub mod baz {
+   |         ^^^^^^^^^^^ not accessible
 
 error[E0432]: unresolved import `food::beens`
   --> $DIR/unresolved-import.rs:19:12
@@ -37,13 +43,13 @@ LL | use food::{beens as Foo};
    |            help: a similar name exists in the module: `beans`
 
 error[E0432]: unresolved import `MyEnum`
-  --> $DIR/unresolved-import.rs:44:9
+  --> $DIR/unresolved-import.rs:46:9
    |
 LL |     use MyEnum::*;
    |         ^^^^^^ help: a similar path exists: `self::MyEnum`
 
 error[E0432]: unresolved import `Enum`
-  --> $DIR/unresolved-import.rs:55:9
+  --> $DIR/unresolved-import.rs:57:9
    |
 LL |     use Enum::*;
    |         ^^^^ help: a similar path exists: `self::Enum`