Skip to content

Commit

Permalink
Rollup merge of #70434 - Centril:fix-34421, r=estebank
Browse files Browse the repository at this point in the history
suggest `;` on expr `mac!()` which is good as stmt `mac!()`

Fixes #34421 by implementing @jseyfried's suggestion in #34421 (comment).

r? @petrochenkov
  • Loading branch information
Centril authored Mar 27, 2020
2 parents 08e867c + 6c643a0 commit cfe1e33
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/librustc_expand/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Pa
fn emit_frag_parse_err(
mut e: DiagnosticBuilder<'_>,
parser: &Parser<'_>,
orig_parser: &mut Parser<'_>,
site_span: Span,
macro_ident: ast::Ident,
arm_span: Span,
Expand Down Expand Up @@ -118,6 +119,21 @@ fn emit_frag_parse_err(
AstFragmentKind::Pat if macro_ident.name == sym::vec => {
suggest_slice_pat(&mut e, site_span, parser);
}
// Try a statement if an expression is wanted but failed and suggest adding `;` to call.
AstFragmentKind::Expr => match parse_ast_fragment(orig_parser, AstFragmentKind::Stmts) {
Err(mut err) => err.cancel(),
Ok(_) => {
e.note(
"the macro call doesn't expand to an expression, but it can expand to a statement",
);
e.span_suggestion_verbose(
site_span.shrink_to_hi(),
"add `;` to interpret the expansion as a statement",
";".to_string(),
Applicability::MaybeIncorrect,
);
}
},
_ => annotate_err_with_kind(&mut e, kind, site_span),
};
e.emit();
Expand All @@ -126,10 +142,11 @@ fn emit_frag_parse_err(
impl<'a> ParserAnyMacro<'a> {
crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
let snapshot = &mut parser.clone();
let fragment = match parse_ast_fragment(parser, kind) {
Ok(f) => f,
Err(err) => {
emit_frag_parse_err(err, parser, site_span, macro_ident, arm_span, kind);
emit_frag_parse_err(err, parser, snapshot, site_span, macro_ident, arm_span, kind);
return kind.dummy(site_span);
}
};
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
macro_rules! make_item {
($a:ident) => {
struct $a;
}; //~^ ERROR expected expression
//~| ERROR expected expression
}

fn a() {
make_item!(A)
}
fn b() {
make_item!(B)
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
error: expected expression, found keyword `struct`
--> $DIR/issue-34421-mac-expr-bad-stmt-good-add-semi.rs:3:9
|
LL | struct $a;
| ^^^^^^ expected expression
...
LL | make_item!(A)
| ------------- in this macro invocation
|
= note: the macro call doesn't expand to an expression, but it can expand to a statement
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `;` to interpret the expansion as a statement
|
LL | make_item!(A);
| ^

error: expected expression, found keyword `struct`
--> $DIR/issue-34421-mac-expr-bad-stmt-good-add-semi.rs:3:9
|
LL | struct $a;
| ^^^^^^ expected expression
...
LL | make_item!(B)
| ------------- in this macro invocation
|
= note: the macro call doesn't expand to an expression, but it can expand to a statement
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `;` to interpret the expansion as a statement
|
LL | make_item!(B);
| ^

error: aborting due to 2 previous errors

6 changes: 6 additions & 0 deletions src/test/ui/macros/macro-in-expression-context-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ LL | macro_rules! empty { () => () }
...
LL | _ => { empty!() }
| ^^^^^^^^ expected expression
|
= note: the macro call doesn't expand to an expression, but it can expand to a statement
help: add `;` to interpret the expansion as a statement
|
LL | _ => { empty!(); }
| ^

error: aborting due to previous error

0 comments on commit cfe1e33

Please sign in to comment.