diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 97c88064e9799..e16645ec0df45 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2116,6 +2116,111 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.field_idents(def_id)?.iter().map(|&f| f.span).reduce(Span::to) // None for `struct Foo()` } + /// Returns the path segments (as symbols) of a module, including `kw::Crate` at the start. + /// For example, for `crate::foo::bar`, returns `[Crate, foo, bar]`. + /// Returns `None` for block modules that don't have a `DefId`. + fn module_path_names(&self, module: Module<'ra>) -> Option> { + let mut path = Vec::new(); + let mut def_id = module.opt_def_id()?; + while let Some(parent) = self.tcx.opt_parent(def_id) { + if let Some(name) = self.tcx.opt_item_name(def_id) { + path.push(name); + } + if parent.is_top_level_module() { + break; + } + def_id = parent; + } + path.reverse(); + path.insert(0, kw::Crate); + Some(path) + } + + /// Shortens a candidate import path to use `super::` (up to 1 level) or `self::` (same module) + /// relative to the current scope, if possible. Only applies to crate-local items and + /// only when the resulting path is actually shorter than the original. + fn shorten_candidate_path( + &self, + suggestion: &mut ImportSuggestion, + current_module: Module<'ra>, + ) { + const MAX_SUPER_PATH_ITEMS_IN_SUGGESTION: usize = 1; + + // Only shorten local items. + if suggestion.did.is_none_or(|did| !did.is_local()) { + return; + } + + // Build current module path: [Crate, foo, bar, ...]. + let Some(current_mod_path) = self.module_path_names(current_module) else { + return; + }; + + // Normalise candidate path: filter out `PathRoot` (`::`), and if the path + // doesn't start with `Crate`, prepend it (edition 2015 paths are relative + // to the crate root without an explicit `crate::` prefix). + let candidate_names = { + let filtered_segments: Vec<_> = suggestion + .path + .segments + .iter() + .filter(|segment| segment.ident.name != kw::PathRoot) + .collect(); + + let mut candidate_names: Vec = + filtered_segments.iter().map(|segment| segment.ident.name).collect(); + if candidate_names.first() != Some(&kw::Crate) { + candidate_names.insert(0, kw::Crate); + } + if candidate_names.len() < 2 { + return; + } + candidate_names + }; + + // The candidate's module path is everything except the last segment (the item name). + let candidate_mod_names = &candidate_names[..candidate_names.len() - 1]; + + // Find the longest common prefix between the current module and candidate module paths. + let common_prefix_length = current_mod_path + .iter() + .zip(candidate_mod_names.iter()) + .take_while(|(current, candidate)| current == candidate) + .count(); + + // Non-crate-local item; keep the full absolute path. + if common_prefix_length == 0 { + return; + } + + let super_count = current_mod_path.len() - common_prefix_length; + + // At the crate root, `use` paths resolve from the crate root anyway, so we can + // drop the `crate::` prefix entirely instead of replacing it with `self::`. + let at_crate_root = current_mod_path.len() == 1; + + let mut new_segments = if super_count == 0 && at_crate_root { + ThinVec::new() + } else { + let prefix_keyword = match super_count { + 0 => kw::SelfLower, + 1..=MAX_SUPER_PATH_ITEMS_IN_SUGGESTION => kw::Super, + _ => return, // Too many `super` levels; keep the full absolute path. + }; + thin_vec![ast::PathSegment::from_ident(Ident::with_dummy_span(prefix_keyword),)] + }; + for &name in &candidate_names[common_prefix_length..] { + new_segments.push(ast::PathSegment::from_ident(Ident::with_dummy_span(name))); + } + + // Only apply if the result is strictly shorter than the original path. + if new_segments.len() >= suggestion.path.segments.len() { + return; + } + + suggestion.path = Path { span: suggestion.path.span, segments: new_segments, tokens: None }; + } + fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) { let PrivacyError { ident, @@ -2144,12 +2249,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut not_publicly_reexported = false; if let Some((this_res, outer_ident)) = outermost_res { - let import_suggestions = self.lookup_import_candidates( + let mut import_suggestions = self.lookup_import_candidates( outer_ident, this_res.ns().unwrap_or(Namespace::TypeNS), &parent_scope, &|res: Res| res == this_res, ); + // Shorten candidate paths using `super::` or `self::` when possible. + for suggestion in &mut import_suggestions { + self.shorten_candidate_path(suggestion, parent_scope.module); + } let point_to_def = !show_candidates( self.tcx, &mut err, diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 6507ee3477379..db098b4a14bc4 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1188,6 +1188,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { for error in &mut self.privacy_errors[privacy_errors_len..] { error.outermost_res = res; } + } else { + // The final item is not a module (e.g., a struct, function, or macro). + // Resolve it directly in the parent module to get its Res, so + // `report_privacy_error()` can search for public re-export paths. + for ns in [TypeNS, ValueNS, MacroNS] { + if let Ok(binding) = self.cm().resolve_ident_in_module( + module, + ident, + ns, + &import.parent_scope, + None, + ignore_decl, + None, + ) { + let res = binding.res(); + for error in &mut self.privacy_errors[privacy_errors_len..] { + error.outermost_res = Some((res, ident)); + } + break; + } + } } } diff --git a/tests/ui/imports/reexports.stderr b/tests/ui/imports/reexports.stderr index 0ebcf8e58d627..cb3836305c1ab 100644 --- a/tests/ui/imports/reexports.stderr +++ b/tests/ui/imports/reexports.stderr @@ -14,7 +14,9 @@ error[E0603]: module import `foo` is private --> $DIR/reexports.rs:36:22 | LL | use crate::b::a::foo::S; - | ^^^ private module import + | ^^^ - struct `S` is not publicly re-exported + | | + | private module import | note: the module import `foo` is defined here... --> $DIR/reexports.rs:24:17 @@ -31,7 +33,9 @@ error[E0603]: module import `foo` is private --> $DIR/reexports.rs:37:22 | LL | use crate::b::b::foo::S as T; - | ^^^ private module import + | ^^^ - struct `S` is not publicly re-exported + | | + | private module import | note: the module import `foo` is defined here... --> $DIR/reexports.rs:29:17 diff --git a/tests/ui/imports/suggest-public-reexport-for-use.edition2015.stderr b/tests/ui/imports/suggest-public-reexport-for-use.edition2015.stderr new file mode 100644 index 0000000000000..815f91a0b6c8a --- /dev/null +++ b/tests/ui/imports/suggest-public-reexport-for-use.edition2015.stderr @@ -0,0 +1,119 @@ +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:27:12 + | +LL | use outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use outer::inner::MyStruct; +LL + use outer::MyStruct; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:28:12 + | +LL | use outer::inner::my_function; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this function through its public re-export instead + | +LL - use outer::inner::my_function; +LL + use outer::my_function; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:29:12 + | +LL | use outer::inner::MyTrait; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this trait through its public re-export instead + | +LL - use outer::inner::MyTrait; +LL + use outer::MyTrait; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:30:12 + | +LL | use outer::inner::MyEnum; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this enum through its public re-export instead + | +LL - use outer::inner::MyEnum; +LL + use outer::MyEnum; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:36:16 + | +LL | use outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use outer::inner::MyStruct; +LL + use outer::MyStruct; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:46:20 + | +LL | use outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use outer::inner::MyStruct; +LL + use outer::MyStruct; + | + +error[E0603]: module `hidden` is private + --> $DIR/suggest-public-reexport-for-use.rs:60:18 + | +LL | use no_reexport::hidden::Secret; + | ^^^^^^ ------ struct `Secret` is not publicly re-exported + | | + | private module + | +note: the module `hidden` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:55:5 + | +LL | mod hidden { + | ^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/imports/suggest-public-reexport-for-use.edition2018.stderr b/tests/ui/imports/suggest-public-reexport-for-use.edition2018.stderr new file mode 100644 index 0000000000000..0295cb29ca3e2 --- /dev/null +++ b/tests/ui/imports/suggest-public-reexport-for-use.edition2018.stderr @@ -0,0 +1,119 @@ +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:27:12 + | +LL | use outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use outer::inner::MyStruct; +LL + use outer::MyStruct; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:28:12 + | +LL | use outer::inner::my_function; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this function through its public re-export instead + | +LL - use outer::inner::my_function; +LL + use outer::my_function; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:29:12 + | +LL | use outer::inner::MyTrait; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this trait through its public re-export instead + | +LL - use outer::inner::MyTrait; +LL + use outer::MyTrait; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:30:12 + | +LL | use outer::inner::MyEnum; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this enum through its public re-export instead + | +LL - use outer::inner::MyEnum; +LL + use outer::MyEnum; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:39:23 + | +LL | use crate::outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use crate::outer::inner::MyStruct; +LL + use crate::outer::MyStruct; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:49:27 + | +LL | use crate::outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use crate::outer::inner::MyStruct; +LL + use crate::outer::MyStruct; + | + +error[E0603]: module `hidden` is private + --> $DIR/suggest-public-reexport-for-use.rs:60:18 + | +LL | use no_reexport::hidden::Secret; + | ^^^^^^ ------ struct `Secret` is not publicly re-exported + | | + | private module + | +note: the module `hidden` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:55:5 + | +LL | mod hidden { + | ^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/imports/suggest-public-reexport-for-use.edition2021.stderr b/tests/ui/imports/suggest-public-reexport-for-use.edition2021.stderr new file mode 100644 index 0000000000000..0295cb29ca3e2 --- /dev/null +++ b/tests/ui/imports/suggest-public-reexport-for-use.edition2021.stderr @@ -0,0 +1,119 @@ +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:27:12 + | +LL | use outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use outer::inner::MyStruct; +LL + use outer::MyStruct; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:28:12 + | +LL | use outer::inner::my_function; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this function through its public re-export instead + | +LL - use outer::inner::my_function; +LL + use outer::my_function; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:29:12 + | +LL | use outer::inner::MyTrait; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this trait through its public re-export instead + | +LL - use outer::inner::MyTrait; +LL + use outer::MyTrait; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:30:12 + | +LL | use outer::inner::MyEnum; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this enum through its public re-export instead + | +LL - use outer::inner::MyEnum; +LL + use outer::MyEnum; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:39:23 + | +LL | use crate::outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use crate::outer::inner::MyStruct; +LL + use crate::outer::MyStruct; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:49:27 + | +LL | use crate::outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use crate::outer::inner::MyStruct; +LL + use crate::outer::MyStruct; + | + +error[E0603]: module `hidden` is private + --> $DIR/suggest-public-reexport-for-use.rs:60:18 + | +LL | use no_reexport::hidden::Secret; + | ^^^^^^ ------ struct `Secret` is not publicly re-exported + | | + | private module + | +note: the module `hidden` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:55:5 + | +LL | mod hidden { + | ^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/imports/suggest-public-reexport-for-use.edition2024.stderr b/tests/ui/imports/suggest-public-reexport-for-use.edition2024.stderr new file mode 100644 index 0000000000000..0295cb29ca3e2 --- /dev/null +++ b/tests/ui/imports/suggest-public-reexport-for-use.edition2024.stderr @@ -0,0 +1,119 @@ +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:27:12 + | +LL | use outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use outer::inner::MyStruct; +LL + use outer::MyStruct; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:28:12 + | +LL | use outer::inner::my_function; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this function through its public re-export instead + | +LL - use outer::inner::my_function; +LL + use outer::my_function; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:29:12 + | +LL | use outer::inner::MyTrait; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this trait through its public re-export instead + | +LL - use outer::inner::MyTrait; +LL + use outer::MyTrait; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:30:12 + | +LL | use outer::inner::MyEnum; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this enum through its public re-export instead + | +LL - use outer::inner::MyEnum; +LL + use outer::MyEnum; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:39:23 + | +LL | use crate::outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use crate::outer::inner::MyStruct; +LL + use crate::outer::MyStruct; + | + +error[E0603]: module `inner` is private + --> $DIR/suggest-public-reexport-for-use.rs:49:27 + | +LL | use crate::outer::inner::MyStruct; + | ^^^^^ private module + | +note: the module `inner` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:16:5 + | +LL | mod inner { + | ^^^^^^^^^ +help: consider importing this struct through its public re-export instead + | +LL - use crate::outer::inner::MyStruct; +LL + use crate::outer::MyStruct; + | + +error[E0603]: module `hidden` is private + --> $DIR/suggest-public-reexport-for-use.rs:60:18 + | +LL | use no_reexport::hidden::Secret; + | ^^^^^^ ------ struct `Secret` is not publicly re-exported + | | + | private module + | +note: the module `hidden` is defined here + --> $DIR/suggest-public-reexport-for-use.rs:55:5 + | +LL | mod hidden { + | ^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/imports/suggest-public-reexport-for-use.rs b/tests/ui/imports/suggest-public-reexport-for-use.rs new file mode 100644 index 0000000000000..1658735e36cf9 --- /dev/null +++ b/tests/ui/imports/suggest-public-reexport-for-use.rs @@ -0,0 +1,62 @@ +//@ revisions: edition2015 edition2018 edition2021 edition2024 +//@ [edition2015] edition:2015 +//@ [edition2018] edition:2018 +//@ [edition2021] edition:2021 +//@ [edition2024] edition:2024 + +// When a `use` statement accesses an item through a private module, +// the compiler should suggest a public re-export if one exists. + +mod outer { + pub use self::inner::MyStruct; + pub use self::inner::my_function; + pub use self::inner::MyTrait; + pub use self::inner::MyEnum; + + mod inner { + pub struct MyStruct; + pub fn my_function() {} + pub trait MyTrait {} + pub enum MyEnum { + Variant, + } + } +} + +// Accessing items through a private module should suggest the public re-export. +use outer::inner::MyStruct; //~ ERROR module `inner` is private +use outer::inner::my_function; //~ ERROR module `inner` is private +use outer::inner::MyTrait; //~ ERROR module `inner` is private +use outer::inner::MyEnum; //~ ERROR module `inner` is private + +// From a sibling module, the suggestion should keep the full path +// (shortening to `super::` would not reduce the segment count here). +mod sibling { + #[cfg(edition2015)] + use outer::inner::MyStruct; //[edition2015]~ ERROR module `inner` is private + + #[cfg(not(edition2015))] + use crate::outer::inner::MyStruct; //[edition2018,edition2021,edition2024]~ ERROR module `inner` is private +} + +// From a deeply nested module, the suggestion should keep the full path. +mod deep { + mod nested { + #[cfg(edition2015)] + use outer::inner::MyStruct; //[edition2015]~ ERROR module `inner` is private + + #[cfg(not(edition2015))] + use crate::outer::inner::MyStruct; //[edition2018,edition2021,edition2024]~ ERROR module `inner` is private + } +} + +// Items with no public re-export should say "not publicly re-exported". +mod no_reexport { + mod hidden { + pub struct Secret; + } +} + +use no_reexport::hidden::Secret; //~ ERROR module `hidden` is private + +fn main() {} diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index f62ef3ae2e4cc..5d1e003c703b4 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -4,6 +4,12 @@ error[E0603]: module `baz` is private LL | use bar::baz::{foo, bar}; | ^^^ private module | +help: consider importing this function through its public re-export instead: + bar::foo + --> $DIR/privacy1.rs:139:24 + | +LL | use bar::baz::{foo, bar}; + | ^^^ note: the module `baz` is defined here --> $DIR/privacy1.rs:57:5 | @@ -16,12 +22,17 @@ error[E0603]: module `baz` is private LL | use bar::baz::{foo, bar}; | ^^^ private module | +help: consider importing this function through its public re-export instead: + bar::bar + --> $DIR/privacy1.rs:139:29 + | +LL | use bar::baz::{foo, bar}; + | ^^^ note: the module `baz` is defined here --> $DIR/privacy1.rs:57:5 | LL | mod baz { | ^^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0603]: module `baz` is private --> $DIR/privacy1.rs:148:18 @@ -39,7 +50,9 @@ error[E0603]: module `i` is private --> $DIR/privacy1.rs:172:20 | LL | use self::foo::i::A; - | ^ private module + | ^ - struct `A` is not publicly re-exported + | | + | private module | note: the module `i` is defined here --> $DIR/privacy1.rs:177:9 diff --git a/tests/ui/shadowed/shadowed-use-visibility.stderr b/tests/ui/shadowed/shadowed-use-visibility.stderr index b062341dc8be8..bbec8380fd032 100644 --- a/tests/ui/shadowed/shadowed-use-visibility.stderr +++ b/tests/ui/shadowed/shadowed-use-visibility.stderr @@ -14,6 +14,11 @@ note: ...and refers to the module `foo` which is defined here | LL | mod foo { | ^^^^^^^ +help: consider importing this function instead + | +LL - use crate::foo::bar::f as g; +LL + use foo::f as g; + | error[E0603]: module import `f` is private --> $DIR/shadowed-use-visibility.rs:15:10 @@ -31,6 +36,11 @@ note: ...and refers to the module `foo` which is defined here | LL | mod foo { | ^^^^^^^ +help: consider importing this function through its public re-export instead + | +LL - use bar::f::f; +LL + use bar::f; + | error: aborting due to 2 previous errors diff --git a/tests/ui/use/use-mod/use-mod-3.stderr b/tests/ui/use/use-mod/use-mod-3.stderr index 1b12b3c6fa09a..2143d09f6b983 100644 --- a/tests/ui/use/use-mod/use-mod-3.stderr +++ b/tests/ui/use/use-mod/use-mod-3.stderr @@ -15,6 +15,8 @@ error[E0603]: module `bar` is private | LL | use foo::bar::{ | ^^^ private module +LL | Bar + | --- type alias `Bar` is not publicly re-exported | note: the module `bar` is defined here --> $DIR/use-mod-3.rs:9:5