diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1dbd7bad0f023..0f8c0e1b8cff8 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1100,30 +1100,37 @@ impl<'a> Parser<'a> { snapshot.bump(); // `(` match snapshot.parse_struct_fields(path, false, 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)`. *self = snapshot; let close_paren = self.prev_token.span; let span = lo.to(self.prev_token.span); - err.cancel(); - self.struct_span_err( - span, - "invalid `struct` delimiters or `fn` call arguments", - ) - .multipart_suggestion( - &format!("if `{}` is a struct, use braces as delimiters", name), - vec![(open_paren, " { ".to_string()), (close_paren, " }".to_string())], - Applicability::MaybeIncorrect, - ) - .multipart_suggestion( - &format!("if `{}` is a function, use the arguments directly", name), - fields - .into_iter() - .map(|field| (field.span.until(field.expr.span), String::new())) - .collect(), - Applicability::MaybeIncorrect, - ) - .emit(); + if !fields.is_empty() { + err.cancel(); + let mut err = self.struct_span_err( + span, + "invalid `struct` delimiters or `fn` call arguments", + ); + err.multipart_suggestion( + &format!("if `{}` is a struct, use braces as delimiters", name), + vec![ + (open_paren, " { ".to_string()), + (close_paren, " }".to_string()), + ], + Applicability::MaybeIncorrect, + ); + err.multipart_suggestion( + &format!("if `{}` is a function, use the arguments directly", name), + fields + .into_iter() + .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)); } Ok(_) => {} diff --git a/src/test/ui/parser/issues/issue-91461.rs b/src/test/ui/parser/issues/issue-91461.rs new file mode 100644 index 0000000000000..3e3c411c478ab --- /dev/null +++ b/src/test/ui/parser/issues/issue-91461.rs @@ -0,0 +1,6 @@ +fn main() { + a(_:b:,) + //~^ ERROR: expected identifier, found reserved identifier `_` + //~| ERROR: expected type, found `,` + //~| ERROR: expected type, found `,` +} diff --git a/src/test/ui/parser/issues/issue-91461.stderr b/src/test/ui/parser/issues/issue-91461.stderr new file mode 100644 index 0000000000000..94fcf1721d8c1 --- /dev/null +++ b/src/test/ui/parser/issues/issue-91461.stderr @@ -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: `: ` + = note: see issue #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: `: ` + = note: see issue #23416 for more information + +error: aborting due to 3 previous errors +