Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 59191 - ICE when macro replaces crate root with non-module item #68758

Merged
merged 3 commits into from
Feb 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/librustc_expand/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crate-level attribute macros aren't really expected to produce a module, they are just not supported at all and may result in nonsense and paradoxes.
This is an ok fix and it removes the ICE, but this case should ideally report the same error as this example:

enum E {
    #[test] // error: expected an inert attribute, found an attribute macro
    V
}

fn main() {}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not urgent though, and I still hope to rewrite the macro invocation collector anyway.

kind.descriptive_variant()
),
);
}
};
self.cx.trace_macros_diag();
krate
Expand Down
16 changes: 16 additions & 0 deletions src/test/ui/proc-macro/auxiliary/issue-59191.rs
Original file line number Diff line number Diff line change
@@ -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()
}
8 changes: 8 additions & 0 deletions src/test/ui/proc-macro/issue-59191-replace-root-with-fn.rs
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions src/test/ui/proc-macro/issue-59191-replace-root-with-fn.stderr
Original file line number Diff line number Diff line change
@@ -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`.