未验证 提交 cfe1e330 编写于 作者: M Mazdak Farrokhzad 提交者: GitHub

Rollup merge of #70434 - Centril:fix-34421, r=estebank

suggest `;` on expr `mac!()` which is good as stmt `mac!()`

Fixes https://github.com/rust-lang/rust/issues/34421 by implementing @jseyfried's suggestion in https://github.com/rust-lang/rust/issues/34421#issuecomment-301578683.

r? @petrochenkov
......@@ -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);
}
};
......
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() {}
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,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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册