Skip to content

Commit cf2d0ce

Browse files
committed
diagnostics: suggest changing s@self::{macro}@::macro for exported
Fixes #99695
1 parent 6284998 commit cf2d0ce

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

compiler/rustc_resolve/src/diagnostics.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -2285,9 +2285,31 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
22852285

22862286
let source_map = self.r.session.source_map();
22872287

2288+
// Make sure this is actually crate-relative.
2289+
let use_and_crate = import.use_span.with_hi(after_crate_name.lo());
2290+
let is_definitely_crate =
2291+
source_map.span_to_snippet(use_and_crate).map_or(false, |s| {
2292+
let mut s = s.trim();
2293+
debug!("check_for_module_export_macro: s={s:?}",);
2294+
s = s
2295+
.split_whitespace()
2296+
.rev()
2297+
.next()
2298+
.expect("split_whitespace always yields at least once");
2299+
debug!("check_for_module_export_macro: s={s:?}",);
2300+
if s.ends_with("::") {
2301+
s = &s[..s.len() - 2];
2302+
} else {
2303+
return false;
2304+
}
2305+
s = s.trim();
2306+
debug!("check_for_module_export_macro: s={s:?}",);
2307+
s != "self" && s != "super"
2308+
});
2309+
22882310
// Add the import to the start, with a `{` if required.
22892311
let start_point = source_map.start_point(after_crate_name);
2290-
if let Ok(start_snippet) = source_map.span_to_snippet(start_point) {
2312+
if is_definitely_crate && let Ok(start_snippet) = source_map.span_to_snippet(start_point) {
22912313
corrections.push((
22922314
start_point,
22932315
if has_nested {
@@ -2299,6 +2321,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
22992321
format!("{{{}, {}", import_snippet, start_snippet)
23002322
},
23012323
));
2324+
} else {
2325+
// If the root import is module-relative, add the import separately
2326+
corrections.push((
2327+
source_map.start_point(import.use_span).shrink_to_lo(),
2328+
format!("use {module_name}::{import_snippet};\n"),
2329+
));
23022330
}
23032331

23042332
// Add a `};` to the end if nested, matching the `{` added at the start.

src/test/ui/imports/issue-99695.fixed

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// run-rustfix
2+
#![allow(unused, nonstandard_style)]
3+
mod m {
4+
#[macro_export]
5+
macro_rules! nu {
6+
{} => {};
7+
}
8+
9+
pub struct other_item;
10+
11+
use ::nu;
12+
pub use self::{other_item as _};
13+
//~^ ERROR unresolved import `self::nu` [E0432]
14+
//~| HELP a macro with this name exists at the root of the crate
15+
}
16+
17+
fn main() {}

src/test/ui/imports/issue-99695.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// run-rustfix
2+
#![allow(unused, nonstandard_style)]
3+
mod m {
4+
#[macro_export]
5+
macro_rules! nu {
6+
{} => {};
7+
}
8+
9+
pub struct other_item;
10+
11+
pub use self::{nu, other_item as _};
12+
//~^ ERROR unresolved import `self::nu` [E0432]
13+
//~| HELP a macro with this name exists at the root of the crate
14+
}
15+
16+
fn main() {}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0432]: unresolved import `self::nu`
2+
--> $DIR/issue-99695.rs:11:20
3+
|
4+
LL | pub use self::{nu, other_item as _};
5+
| ^^ no `nu` in `m`
6+
|
7+
= 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
8+
help: a macro with this name exists at the root of the crate
9+
|
10+
LL ~ use ::nu;
11+
LL ~ pub use self::{other_item as _};
12+
|
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0432`.

0 commit comments

Comments
 (0)