diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index f24e405018b..8d104aa5cc5 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2125,9 +2125,15 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let source_map = self.r.session.source_map(); + // Make sure this is actually crate-relative. + let is_definitely_crate = import + .module_path + .first() + .map_or(false, |f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super); + // Add the import to the start, with a `{` if required. let start_point = source_map.start_point(after_crate_name); - if let Ok(start_snippet) = source_map.span_to_snippet(start_point) { + if is_definitely_crate && let Ok(start_snippet) = source_map.span_to_snippet(start_point) { corrections.push(( start_point, if has_nested { @@ -2139,11 +2145,17 @@ impl<'a, 'b> ImportResolver<'a, 'b> { format!("{{{}, {}", import_snippet, start_snippet) }, )); - } - // Add a `};` to the end if nested, matching the `{` added at the start. - if !has_nested { - corrections.push((source_map.end_point(after_crate_name), "};".to_string())); + // Add a `};` to the end if nested, matching the `{` added at the start. + if !has_nested { + corrections.push((source_map.end_point(after_crate_name), "};".to_string())); + } + } else { + // If the root import is module-relative, add the import separately + corrections.push(( + import.use_span.shrink_to_lo(), + format!("use {module_name}::{import_snippet};\n"), + )); } } diff --git a/tests/ui/imports/issue-99695-b.fixed b/tests/ui/imports/issue-99695-b.fixed new file mode 100644 index 00000000000..0e60c73b67a --- /dev/null +++ b/tests/ui/imports/issue-99695-b.fixed @@ -0,0 +1,20 @@ +// run-rustfix +#![allow(unused, nonstandard_style)] +mod m { + + mod p { + #[macro_export] + macro_rules! nu { + {} => {}; + } + + pub struct other_item; + } + + use ::nu; +pub use self::p::{other_item as _}; + //~^ ERROR unresolved import `self::p::nu` [E0432] + //~| HELP a macro with this name exists at the root of the crate +} + +fn main() {} diff --git a/tests/ui/imports/issue-99695-b.rs b/tests/ui/imports/issue-99695-b.rs new file mode 100644 index 00000000000..031443a1f5d --- /dev/null +++ b/tests/ui/imports/issue-99695-b.rs @@ -0,0 +1,19 @@ +// run-rustfix +#![allow(unused, nonstandard_style)] +mod m { + + mod p { + #[macro_export] + macro_rules! nu { + {} => {}; + } + + pub struct other_item; + } + + pub use self::p::{nu, other_item as _}; + //~^ ERROR unresolved import `self::p::nu` [E0432] + //~| HELP a macro with this name exists at the root of the crate +} + +fn main() {} diff --git a/tests/ui/imports/issue-99695-b.stderr b/tests/ui/imports/issue-99695-b.stderr new file mode 100644 index 00000000000..b6f5c726a5c --- /dev/null +++ b/tests/ui/imports/issue-99695-b.stderr @@ -0,0 +1,16 @@ +error[E0432]: unresolved import `self::p::nu` + --> $DIR/issue-99695-b.rs:14:23 + | +LL | pub use self::p::{nu, other_item as _}; + | ^^ no `nu` in `m::p` + | + = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined +help: a macro with this name exists at the root of the crate + | +LL ~ use ::nu; +LL ~ pub use self::p::{other_item as _}; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/imports/issue-99695.fixed b/tests/ui/imports/issue-99695.fixed new file mode 100644 index 00000000000..6bf228b23aa --- /dev/null +++ b/tests/ui/imports/issue-99695.fixed @@ -0,0 +1,17 @@ +// run-rustfix +#![allow(unused, nonstandard_style)] +mod m { + #[macro_export] + macro_rules! nu { + {} => {}; + } + + pub struct other_item; + + use ::nu; +pub use self::{other_item as _}; + //~^ ERROR unresolved import `self::nu` [E0432] + //~| HELP a macro with this name exists at the root of the crate +} + +fn main() {} diff --git a/tests/ui/imports/issue-99695.rs b/tests/ui/imports/issue-99695.rs new file mode 100644 index 00000000000..f7199f1497a --- /dev/null +++ b/tests/ui/imports/issue-99695.rs @@ -0,0 +1,16 @@ +// run-rustfix +#![allow(unused, nonstandard_style)] +mod m { + #[macro_export] + macro_rules! nu { + {} => {}; + } + + pub struct other_item; + + pub use self::{nu, other_item as _}; + //~^ ERROR unresolved import `self::nu` [E0432] + //~| HELP a macro with this name exists at the root of the crate +} + +fn main() {} diff --git a/tests/ui/imports/issue-99695.stderr b/tests/ui/imports/issue-99695.stderr new file mode 100644 index 00000000000..0ef762e1c82 --- /dev/null +++ b/tests/ui/imports/issue-99695.stderr @@ -0,0 +1,16 @@ +error[E0432]: unresolved import `self::nu` + --> $DIR/issue-99695.rs:11:20 + | +LL | pub use self::{nu, other_item as _}; + | ^^ no `nu` in `m` + | + = note: this could be because a macro annotated with `#[macro_export]` will be exported at the root of the crate instead of the module where it is defined +help: a macro with this name exists at the root of the crate + | +LL ~ use ::nu; +LL ~ pub use self::{other_item as _}; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0432`.