Do not attempt to suggest help for overly malformed struct/function call

This commit is contained in:
threadexception 2021-12-07 16:44:51 +01:00
parent 887999d163
commit b4c4bc09dd
3 changed files with 64 additions and 20 deletions

View File

@ -1100,30 +1100,37 @@ impl<'a> Parser<'a> {
snapshot.bump(); // `(` snapshot.bump(); // `(`
match snapshot.parse_struct_fields(path, false, token::Paren) { match snapshot.parse_struct_fields(path, false, token::Paren) {
Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => { Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => {
// We have are certain we have `Enum::Foo(a: 3, b: 4)`, suggest // We are certain we have `Enum::Foo(a: 3, b: 4)`, suggest
// `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`. // `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`.
*self = snapshot; *self = snapshot;
let close_paren = self.prev_token.span; let close_paren = self.prev_token.span;
let span = lo.to(self.prev_token.span); let span = lo.to(self.prev_token.span);
err.cancel(); if !fields.is_empty() {
self.struct_span_err( err.cancel();
span, let mut err = self.struct_span_err(
"invalid `struct` delimiters or `fn` call arguments", span,
) "invalid `struct` delimiters or `fn` call arguments",
.multipart_suggestion( );
&format!("if `{}` is a struct, use braces as delimiters", name), err.multipart_suggestion(
vec![(open_paren, " { ".to_string()), (close_paren, " }".to_string())], &format!("if `{}` is a struct, use braces as delimiters", name),
Applicability::MaybeIncorrect, vec![
) (open_paren, " { ".to_string()),
.multipart_suggestion( (close_paren, " }".to_string()),
&format!("if `{}` is a function, use the arguments directly", name), ],
fields Applicability::MaybeIncorrect,
.into_iter() );
.map(|field| (field.span.until(field.expr.span), String::new())) err.multipart_suggestion(
.collect(), &format!("if `{}` is a function, use the arguments directly", name),
Applicability::MaybeIncorrect, fields
) .into_iter()
.emit(); .map(|field| (field.span.until(field.expr.span), String::new()))
.collect(),
Applicability::MaybeIncorrect,
);
err.emit();
} else {
err.emit();
}
return Some(self.mk_expr_err(span)); return Some(self.mk_expr_err(span));
} }
Ok(_) => {} Ok(_) => {}

View File

@ -0,0 +1,6 @@
fn main() {
a(_:b:,)
//~^ ERROR: expected identifier, found reserved identifier `_`
//~| ERROR: expected type, found `,`
//~| ERROR: expected type, found `,`
}

View File

@ -0,0 +1,31 @@
error: expected identifier, found reserved identifier `_`
--> $DIR/issue-91461.rs:2:7
|
LL | a(_:b:,)
| ^ expected identifier, found reserved identifier
error: expected type, found `,`
--> $DIR/issue-91461.rs:2:11
|
LL | a(_:b:,)
| - -^ expected type
| | |
| | tried to parse a type due to this type ascription
| while parsing this struct
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
= note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
error: expected type, found `,`
--> $DIR/issue-91461.rs:2:11
|
LL | a(_:b:,)
| -^ expected type
| |
| tried to parse a type due to this type ascription
|
= note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
= note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
error: aborting due to 3 previous errors