about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-01-20 21:33:21 -0500
committerGitHub <noreply@github.com>2023-01-20 21:33:21 -0500
commitbf75f8177b42da40faef510838eb1114c30c49df (patch)
tree50fa13a895a5e85fd82c35cd503f24d8ed1404b9
parente6400693b8a73840288042356dddc74ec64170ef (diff)
parentc07a722847497233e6590d62a3d63946409385c3 (diff)
downloadrust-bf75f8177b42da40faef510838eb1114c30c49df.tar.gz
rust-bf75f8177b42da40faef510838eb1114c30c49df.zip
Rollup merge of #104347 - notriddle:notriddle/import-macro-from-self-fixup, r=TaKO8Ki
diagnostics: suggest changing `s@self::{macro}@::macro` for exported

Fixes #99695
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs22
-rw-r--r--tests/ui/imports/issue-99695-b.fixed20
-rw-r--r--tests/ui/imports/issue-99695-b.rs19
-rw-r--r--tests/ui/imports/issue-99695-b.stderr16
-rw-r--r--tests/ui/imports/issue-99695.fixed17
-rw-r--r--tests/ui/imports/issue-99695.rs16
-rw-r--r--tests/ui/imports/issue-99695.stderr16
7 files changed, 121 insertions, 5 deletions
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`.