diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-03-26 15:54:47 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-03-27 07:02:50 +0100 |
| commit | 6c643a070c1f725159e626697f13b45b72f23069 (patch) | |
| tree | b3584cd88c7d297611e6e03045434fd81d962935 | |
| parent | 3b1d7351186a073c72e4be3c7d7b7ab8f1f10c58 (diff) | |
| download | rust-6c643a070c1f725159e626697f13b45b72f23069.tar.gz rust-6c643a070c1f725159e626697f13b45b72f23069.zip | |
suggest semi on expr mac!() good as stmt mac!().
4 files changed, 73 insertions, 1 deletions
diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs index b9477be57dd..0e70fdbd9c1 100644 --- a/src/librustc_expand/mbe/macro_rules.rs +++ b/src/librustc_expand/mbe/macro_rules.rs @@ -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, @@ -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(); @@ -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); } }; diff --git a/src/test/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.rs b/src/test/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.rs new file mode 100644 index 00000000000..d7813936554 --- /dev/null +++ b/src/test/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.rs @@ -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() {} diff --git a/src/test/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.stderr b/src/test/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.stderr new file mode 100644 index 00000000000..c8d69640071 --- /dev/null +++ b/src/test/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.stderr @@ -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 + diff --git a/src/test/ui/macros/macro-in-expression-context-2.stderr b/src/test/ui/macros/macro-in-expression-context-2.stderr index 672871c49ca..8f966096393 100644 --- a/src/test/ui/macros/macro-in-expression-context-2.stderr +++ b/src/test/ui/macros/macro-in-expression-context-2.stderr @@ -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 |
