suggest semi on expr mac!() good as stmt mac!().
This commit is contained in:
parent
3b1d735118
commit
6c643a070c
4 changed files with 73 additions and 1 deletions
|
@ -86,6 +86,7 @@ fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Pa
|
||||||
fn emit_frag_parse_err(
|
fn emit_frag_parse_err(
|
||||||
mut e: DiagnosticBuilder<'_>,
|
mut e: DiagnosticBuilder<'_>,
|
||||||
parser: &Parser<'_>,
|
parser: &Parser<'_>,
|
||||||
|
orig_parser: &mut Parser<'_>,
|
||||||
site_span: Span,
|
site_span: Span,
|
||||||
macro_ident: ast::Ident,
|
macro_ident: ast::Ident,
|
||||||
arm_span: Span,
|
arm_span: Span,
|
||||||
|
@ -118,6 +119,21 @@ fn emit_frag_parse_err(
|
||||||
AstFragmentKind::Pat if macro_ident.name == sym::vec => {
|
AstFragmentKind::Pat if macro_ident.name == sym::vec => {
|
||||||
suggest_slice_pat(&mut e, site_span, parser);
|
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),
|
_ => annotate_err_with_kind(&mut e, kind, site_span),
|
||||||
};
|
};
|
||||||
e.emit();
|
e.emit();
|
||||||
|
@ -126,10 +142,11 @@ fn emit_frag_parse_err(
|
||||||
impl<'a> ParserAnyMacro<'a> {
|
impl<'a> ParserAnyMacro<'a> {
|
||||||
crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
|
crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
|
||||||
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
|
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) {
|
let fragment = match parse_ast_fragment(parser, kind) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => {
|
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);
|
return kind.dummy(site_span);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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() {}
|
|
@ -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,6 +6,12 @@ LL | macro_rules! empty { () => () }
|
||||||
...
|
...
|
||||||
LL | _ => { empty!() }
|
LL | _ => { empty!() }
|
||||||
| ^^^^^^^^ expected expression
|
| ^^^^^^^^ 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue