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.
This commit is contained in:
Dylan DPC 2020-02-04 21:51:50 +01:00 committed by GitHub
commit 48ea0fa416
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 1 deletions

View file

@ -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

View file

@ -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()
}

View file

@ -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

View file

@ -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`.