Skip to content

Commit 48ea0fa

Browse files
authored
Rollup merge of rust-lang#68758 - daboross:fix-59191, r=petrochenkov
Fix 59191 - ICE when macro replaces crate root with non-module item Hi, This should fix rust-lang#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 rust-lang#54726, though.
2 parents 1921fc0 + 152811d commit 48ea0fa

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

src/librustc_expand/expand.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
363363
krate.attrs = vec![];
364364
krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
365365
}
366-
_ => unreachable!(),
366+
Some(ast::Item { span, kind, .. }) => {
367+
krate.attrs = vec![];
368+
krate.module = ast::Mod { inner: orig_mod_span, items: vec![], inline: true };
369+
self.cx.span_err(
370+
span,
371+
&format!(
372+
"expected crate top-level item to be a module after macro expansion, found a {}",
373+
kind.descriptive_variant()
374+
),
375+
);
376+
}
367377
};
368378
self.cx.trace_macros_diag();
369379
krate
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// edition:2018
2+
// force-host
3+
// no-prefer-dynamic
4+
5+
#![crate_type = "proc-macro"]
6+
7+
extern crate proc_macro;
8+
use proc_macro::TokenStream;
9+
10+
#[proc_macro_attribute]
11+
pub fn no_main(_attrs: TokenStream, _input: TokenStream) -> TokenStream {
12+
let new_krate = r#"
13+
fn main() {}
14+
"#;
15+
new_krate.parse().unwrap()
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// edition:2018
2+
// aux-crate:issue_59191=issue-59191.rs
3+
// Test that using a macro to replace the entire crate tree with a non-'mod' item errors out nicely.
4+
// `issue_59191::no_main` replaces whatever's passed in with `fn main() {}`.
5+
#![feature(custom_inner_attributes)]
6+
//~^ ERROR `main` function not found in crate `issue_59191_replace_root_with_fn` [E0601]
7+
#![issue_59191::no_main]
8+
//~^ ERROR expected crate top-level item to be a module after macro expansion, found a function
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: expected crate top-level item to be a module after macro expansion, found a function
2+
--> $DIR/issue-59191-replace-root-with-fn.rs:7:1
3+
|
4+
LL | #![issue_59191::no_main]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error[E0601]: `main` function not found in crate `issue_59191_replace_root_with_fn`
8+
--> $DIR/issue-59191-replace-root-with-fn.rs:5:1
9+
|
10+
LL | / #![feature(custom_inner_attributes)]
11+
LL | |
12+
LL | | #![issue_59191::no_main]
13+
| |________________________^ consider adding a `main` function to `$DIR/issue-59191-replace-root-with-fn.rs`
14+
15+
error: aborting due to 2 previous errors
16+
17+
For more information about this error, try `rustc --explain E0601`.

0 commit comments

Comments
 (0)