Skip to content

Commit 28aec31

Browse files
committed
mbe: Recover from an attr rule without parentheses
Emit the error, but parse the macro definition as if it had parentheses, to go on and emit other errors.
1 parent a1d7f1f commit 28aec31

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ pub fn compile_declarative_macro(
564564
return dummy_syn_ext(guar);
565565
}
566566
let args = p.parse_token_tree();
567-
check_emission(check_args_parens(sess, &args));
567+
check_args_parens(sess, &args);
568568
let args = parse_one_tt(args, RulePart::Pattern, sess, node_id, features, edition);
569569
check_emission(check_lhs(sess, node_id, &args));
570570
if let Some(guar) = check_no_eof(sess, &p, "expected macro attr body") {
@@ -651,17 +651,16 @@ fn check_no_eof(sess: &Session, p: &Parser<'_>, msg: &'static str) -> Option<Err
651651
None
652652
}
653653

654-
fn check_args_parens(sess: &Session, args: &tokenstream::TokenTree) -> Result<(), ErrorGuaranteed> {
654+
fn check_args_parens(sess: &Session, args: &tokenstream::TokenTree) {
655655
// This does not handle the non-delimited case; that gets handled separately by `check_lhs`.
656656
if let tokenstream::TokenTree::Delimited(dspan, _, delim, _) = args
657657
&& *delim != Delimiter::Parenthesis
658658
{
659-
return Err(sess.dcx().emit_err(errors::MacroArgsBadDelim {
659+
sess.dcx().emit_err(errors::MacroArgsBadDelim {
660660
span: dspan.entire(),
661661
sugg: errors::MacroArgsBadDelimSugg { open: dspan.open, close: dspan.close },
662-
}));
662+
});
663663
}
664-
Ok(())
665664
}
666665

667666
fn check_lhs(sess: &Session, node_id: NodeId, lhs: &mbe::TokenTree) -> Result<(), ErrorGuaranteed> {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![crate_type = "lib"]
2+
#![feature(macro_attr)]
3+
4+
macro_rules! attr {
5+
attr[$($args:tt)*] { $($body:tt)* } => {
6+
//~^ ERROR: macro attribute argument matchers require parentheses
7+
//~v ERROR: attr:
8+
compile_error!(concat!(
9+
"attr: args=\"",
10+
stringify!($($args)*),
11+
"\" body=\"",
12+
stringify!($($body)*),
13+
"\"",
14+
));
15+
};
16+
}
17+
18+
#[attr]
19+
struct S;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error: macro attribute argument matchers require parentheses
2+
--> $DIR/macro-attr-recovery.rs:5:9
3+
|
4+
LL | attr[$($args:tt)*] { $($body:tt)* } => {
5+
| ^^^^^^^^^^^^^^
6+
|
7+
help: the delimiters should be `(` and `)`
8+
|
9+
LL - attr[$($args:tt)*] { $($body:tt)* } => {
10+
LL + attr($($args:tt)*) { $($body:tt)* } => {
11+
|
12+
13+
error: attr: args="" body="struct S;"
14+
--> $DIR/macro-attr-recovery.rs:8:9
15+
|
16+
LL | / compile_error!(concat!(
17+
LL | | "attr: args=\"",
18+
LL | | stringify!($($args)*),
19+
LL | | "\" body=\"",
20+
LL | | stringify!($($body)*),
21+
LL | | "\"",
22+
LL | | ));
23+
| |__________^
24+
...
25+
LL | #[attr]
26+
| ------- in this attribute macro expansion
27+
|
28+
= note: this error originates in the attribute macro `attr` (in Nightly builds, run with -Z macro-backtrace for more info)
29+
30+
error: aborting due to 2 previous errors
31+

0 commit comments

Comments
 (0)