about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-02-04 21:51:50 +0100
committerGitHub <noreply@github.com>2020-02-04 21:51:50 +0100
commit48ea0fa416077e89f036c5081020730a7743df88 (patch)
tree00fe341a535b9fb9ee18ba4ab70f6f40a993768c
parent1921fc099403a2d1bc030771a9976573339d9ec5 (diff)
parent152811d8bf389fce7328ba7bc50c26c34afb0d81 (diff)
downloadrust-48ea0fa416077e89f036c5081020730a7743df88.tar.gz
rust-48ea0fa416077e89f036c5081020730a7743df88.zip
Rollup merge of #68758 - daboross:fix-59191, r=petrochenkov
Fix 59191 - ICE when macro replaces crate root with non-module item

Hi,

This should fix #59191! My friend and I are working on learning the rustc codebase through contributions, so please feel free to mention anything amiss or that could be done better.

The code adds an explicit case for when a macro applied to the crate root (via an inner attribute) replaces it with something nonsensical, like a function. The crate root must be a module, and the error message reflects this.

---

I should note that there are a few other weird edge cases here, like if they do output a module, it succeeds but uses that module's name as a prefix for all names in the crate. I'm assuming that's an issue for stabilizing #54726, though.
-rw-r--r--src/librustc_expand/expand.rs12
-rw-r--r--src/test/ui/proc-macro/auxiliary/issue-59191.rs16
-rw-r--r--src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs8
-rw-r--r--src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr17
4 files changed, 52 insertions, 1 deletions
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index f08bed57315..0b8cbd3a783 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -363,7 +363,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 krate.attrs = vec![];
                 krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
             }
-            _ => unreachable!(),
+            Some(ast::Item { span, kind, .. }) => {
+                krate.attrs = vec![];
+                krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
+                self.cx.span_err(
+                    span,
+                    &format!(
+                        "expected crate top-level item to be a module after macro expansion, found a {}",
+                        kind.descriptive_variant()
+                    ),
+                );
+            }
         };
         self.cx.trace_macros_diag();
         krate
diff --git a/src/test/ui/proc-macro/auxiliary/issue-59191.rs b/src/test/ui/proc-macro/auxiliary/issue-59191.rs
new file mode 100644
index 00000000000..d9ee77067ec
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/issue-59191.rs
@@ -0,0 +1,16 @@
+// edition:2018
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn no_main(_attrs: TokenStream, _input: TokenStream) -> TokenStream {
+    let new_krate = r#"
+        fn main() {}
+    "#;
+    new_krate.parse().unwrap()
+}
diff --git a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs
new file mode 100644
index 00000000000..a59cacb8bde
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs
@@ -0,0 +1,8 @@
+// edition:2018
+// aux-crate:issue_59191=issue-59191.rs
+// Test that using a macro to replace the entire crate tree with a non-'mod' item errors out nicely.
+// `issue_59191::no_main` replaces whatever's passed in with `fn main() {}`.
+#![feature(custom_inner_attributes)]
+//~^ ERROR `main` function not found in crate `issue_59191_replace_root_with_fn` [E0601]
+#![issue_59191::no_main]
+//~^ ERROR expected crate top-level item to be a module after macro expansion, found a function
diff --git a/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr
new file mode 100644
index 00000000000..e0a3caef9db
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr
@@ -0,0 +1,17 @@
+error: expected crate top-level item to be a module after macro expansion, found a function
+  --> $DIR/issue-59191-replace-root-with-fn.rs:7:1
+   |
+LL | #![issue_59191::no_main]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0601]: `main` function not found in crate `issue_59191_replace_root_with_fn`
+  --> $DIR/issue-59191-replace-root-with-fn.rs:5:1
+   |
+LL | / #![feature(custom_inner_attributes)]
+LL | |
+LL | | #![issue_59191::no_main]
+   | |________________________^ consider adding a `main` function to `$DIR/issue-59191-replace-root-with-fn.rs`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0601`.