mark the suggestion as directly when it is

This commit is contained in:
Iris Shi
2026-05-07 23:51:35 +08:00
parent 05b97f76a4
commit 1ad59ef182
6 changed files with 41 additions and 35 deletions
+29 -23
View File
@@ -2307,7 +2307,6 @@ fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) {
self.mention_default_field_values(source, ident, &mut err);
let mut not_publicly_reexported = false;
if let Some((this_res, outer_ident)) = outermost_res {
let mut import_suggestions = self.lookup_import_candidates(
outer_ident,
@@ -2332,7 +2331,6 @@ fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) {
);
// If we suggest importing a public re-export, don't point at the definition.
if point_to_def && ident.span != outer_ident.span {
not_publicly_reexported = true;
let label = errors::OuterIdentIsNotPubliclyReexported {
span: outer_ident.span,
outer_ident_descr: this_res.descr(),
@@ -2428,7 +2426,7 @@ fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) {
};
match binding.kind {
DeclKind::Import { import, .. } => {
DeclKind::Import { source_decl, import, .. } => {
for segment in &import.module_path {
// Don't include `{{root}}` in suggestions - it's an internal symbol
// that should never be shown to users.
@@ -2436,9 +2434,10 @@ fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) {
path.push(segment.ident);
}
}
let through_reexport = !matches!(source_decl.kind, DeclKind::Def(_));
sugg_paths.push((
path.iter().cloned().chain(std::iter::once(ident)).collect::<Vec<_>>(),
true, // re-export
through_reexport,
));
}
DeclKind::Def(_) => {}
@@ -2472,27 +2471,34 @@ fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) {
};
err.subdiagnostic(note);
}
// We prioritize shorter paths, non-core imports and direct imports over the alternatives.
sugg_paths.sort_by_key(|(p, reexport)| (p.len(), p[0].name == sym::core, *reexport));
// In nested imports `dedup_span` is just the inner ident, so a full path
// substitution would produce invalid code. See #156060.
for (sugg, reexport) in sugg_paths {
if not_publicly_reexported || single_nested {
// The suggestion replaces `dedup_span` with a path reaching the failing ident.
// That's valid only when
// 1) the failing ident is the imported leaf, otherwise `as` renames and trailing segments
// get dropped, and
// 2) the use isn't nested, otherwise `dedup_span` is one ident in `{...}`.
//
// See issue #156060.
let can_replace_use =
!single_nested && !outermost_res.is_some_and(|(_, outer)| outer.span != ident.span);
if can_replace_use {
// We prioritize shorter paths, non-core imports and direct imports over the
// alternatives.
sugg_paths.sort_by_key(|(p, reexport)| (p.len(), p[0].name == sym::core, *reexport));
for (sugg, reexport) in sugg_paths {
if sugg.len() <= 1 {
// A single path segment suggestion is wrong. This happens on circular
// imports. `tests/ui/imports/issue-55884-2.rs`
continue;
}
let path = join_path_idents(sugg);
let sugg = if reexport {
errors::ImportIdent::ThroughReExport { span: dedup_span, ident, path }
} else {
errors::ImportIdent::Directly { span: dedup_span, ident, path }
};
err.subdiagnostic(sugg);
break;
}
if sugg.len() <= 1 {
// A single path segment suggestion is wrong. This happens on circular imports.
// `tests/ui/imports/issue-55884-2.rs`
continue;
}
let path = join_path_idents(sugg);
let sugg = if reexport {
errors::ImportIdent::ThroughReExport { span: dedup_span, ident, path }
} else {
errors::ImportIdent::Directly { span: dedup_span, ident, path }
};
err.subdiagnostic(sugg);
break;
}
err.emit();
@@ -14,7 +14,7 @@ note: ...and refers to the struct `S` which is defined here
|
LL | pub struct S {}
| ^^^^^^^^^^^^ you could import this directly
help: import `S` through the re-export
help: import `S` directly
|
LL - use crate::both::private::S;
LL + use crate::m::S;
@@ -36,7 +36,7 @@ note: ...and refers to the struct `S` which is defined here
|
LL | pub struct S {}
| ^^^^^^^^^^^^ you could import this directly
help: import `S` through the re-export
help: import `S` directly
|
LL - use crate::both::private::S;
LL + use crate::m::S;
@@ -1,20 +1,20 @@
error[E0603]: struct import `One` is private
--> $DIR/private-import-suggestion-path-156244-edition2015.rs:16:14
--> $DIR/private-import-suggestion-path-156244-edition2015.rs:12:14
|
LL | use two::One;
| ^^^ private struct import
|
note: the struct import `One` is defined here...
--> $DIR/private-import-suggestion-path-156244-edition2015.rs:12:9
--> $DIR/private-import-suggestion-path-156244-edition2015.rs:8:9
|
LL | use one::One;
| ^^^^^^^^
note: ...and refers to the struct `One` which is defined here
--> $DIR/private-import-suggestion-path-156244-edition2015.rs:8:5
--> $DIR/private-import-suggestion-path-156244-edition2015.rs:4:5
|
LL | pub struct One();
| ^^^^^^^^^^^^^^^^^ you could import this directly
help: import `One` through the re-export
help: import `One` directly
|
LL - use two::One;
LL + use one::One;
@@ -1,20 +1,20 @@
error[E0603]: struct import `One` is private
--> $DIR/private-import-suggestion-path-156244.rs:15:21
--> $DIR/private-import-suggestion-path-156244.rs:12:21
|
LL | use crate::two::One;
| ^^^ private struct import
|
note: the struct import `One` is defined here...
--> $DIR/private-import-suggestion-path-156244.rs:11:9
--> $DIR/private-import-suggestion-path-156244.rs:8:9
|
LL | use crate::one::One;
| ^^^^^^^^^^^^^^^
note: ...and refers to the struct `One` which is defined here
--> $DIR/private-import-suggestion-path-156244.rs:7:5
--> $DIR/private-import-suggestion-path-156244.rs:4:5
|
LL | pub struct One();
| ^^^^^^^^^^^^^^^^^ you could import this directly
help: import `One` through the re-export
help: import `One` directly
|
LL - use crate::two::One;
LL + use crate::one::One;
@@ -13,7 +13,7 @@ note: ...and refers to the module `mem` which is defined here
--> $SRC_DIR/std/src/lib.rs:LL:COL
|
= note: you could import this directly
help: import `mem` through the re-export
help: import `mem` directly
|
LL - use foo::mem;
LL + use std::mem;
+1 -1
View File
@@ -20,7 +20,7 @@ note: ...and refers to the function `foo` which is defined here
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^ you could import this directly
help: import `foo` through the re-export
help: import `foo` directly
|
LL - use bar::glob::foo;
LL + use crate::foo;