Skip to content

Commit cfe1e33

Browse files
authored
Rollup merge of #70434 - Centril:fix-34421, r=estebank
suggest `;` on expr `mac!()` which is good as stmt `mac!()` Fixes #34421 by implementing @jseyfried's suggestion in #34421 (comment). r? @petrochenkov
2 parents 08e867c + 6c643a0 commit cfe1e33

4 files changed

+73
-1
lines changed

src/librustc_expand/mbe/macro_rules.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Pa
8686
fn emit_frag_parse_err(
8787
mut e: DiagnosticBuilder<'_>,
8888
parser: &Parser<'_>,
89+
orig_parser: &mut Parser<'_>,
8990
site_span: Span,
9091
macro_ident: ast::Ident,
9192
arm_span: Span,
@@ -118,6 +119,21 @@ fn emit_frag_parse_err(
118119
AstFragmentKind::Pat if macro_ident.name == sym::vec => {
119120
suggest_slice_pat(&mut e, site_span, parser);
120121
}
122+
// Try a statement if an expression is wanted but failed and suggest adding `;` to call.
123+
AstFragmentKind::Expr => match parse_ast_fragment(orig_parser, AstFragmentKind::Stmts) {
124+
Err(mut err) => err.cancel(),
125+
Ok(_) => {
126+
e.note(
127+
"the macro call doesn't expand to an expression, but it can expand to a statement",
128+
);
129+
e.span_suggestion_verbose(
130+
site_span.shrink_to_hi(),
131+
"add `;` to interpret the expansion as a statement",
132+
";".to_string(),
133+
Applicability::MaybeIncorrect,
134+
);
135+
}
136+
},
121137
_ => annotate_err_with_kind(&mut e, kind, site_span),
122138
};
123139
e.emit();
@@ -126,10 +142,11 @@ fn emit_frag_parse_err(
126142
impl<'a> ParserAnyMacro<'a> {
127143
crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
128144
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
145+
let snapshot = &mut parser.clone();
129146
let fragment = match parse_ast_fragment(parser, kind) {
130147
Ok(f) => f,
131148
Err(err) => {
132-
emit_frag_parse_err(err, parser, site_span, macro_ident, arm_span, kind);
149+
emit_frag_parse_err(err, parser, snapshot, site_span, macro_ident, arm_span, kind);
133150
return kind.dummy(site_span);
134151
}
135152
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
macro_rules! make_item {
2+
($a:ident) => {
3+
struct $a;
4+
}; //~^ ERROR expected expression
5+
//~| ERROR expected expression
6+
}
7+
8+
fn a() {
9+
make_item!(A)
10+
}
11+
fn b() {
12+
make_item!(B)
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error: expected expression, found keyword `struct`
2+
--> $DIR/issue-34421-mac-expr-bad-stmt-good-add-semi.rs:3:9
3+
|
4+
LL | struct $a;
5+
| ^^^^^^ expected expression
6+
...
7+
LL | make_item!(A)
8+
| ------------- in this macro invocation
9+
|
10+
= note: the macro call doesn't expand to an expression, but it can expand to a statement
11+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
12+
help: add `;` to interpret the expansion as a statement
13+
|
14+
LL | make_item!(A);
15+
| ^
16+
17+
error: expected expression, found keyword `struct`
18+
--> $DIR/issue-34421-mac-expr-bad-stmt-good-add-semi.rs:3:9
19+
|
20+
LL | struct $a;
21+
| ^^^^^^ expected expression
22+
...
23+
LL | make_item!(B)
24+
| ------------- in this macro invocation
25+
|
26+
= note: the macro call doesn't expand to an expression, but it can expand to a statement
27+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
28+
help: add `;` to interpret the expansion as a statement
29+
|
30+
LL | make_item!(B);
31+
| ^
32+
33+
error: aborting due to 2 previous errors
34+

src/test/ui/macros/macro-in-expression-context-2.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ LL | macro_rules! empty { () => () }
66
...
77
LL | _ => { empty!() }
88
| ^^^^^^^^ expected expression
9+
|
10+
= note: the macro call doesn't expand to an expression, but it can expand to a statement
11+
help: add `;` to interpret the expansion as a statement
12+
|
13+
LL | _ => { empty!(); }
14+
| ^
915

1016
error: aborting due to previous error
1117

0 commit comments

Comments
 (0)