Change:
This erroneous code: Produces this error message It would be better if instead it produced an error message like this: Tried the code in these Rust versions and they all produced the same error message: 1.37.0 stable1.45.0 stable1.46.0-beta.1 (2020-07-15 )1.47.0-nightly (2020-07-22 ) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
This shouldn't be too hard. This comes from the parser, specifically the code that parses a pattern, which is one of functions. Somewhere there is the code to parse a struct pattern. I assume the error above happens when it successfully parses a struct field and then expects a comma or closing brace. To fix it you'd have to check for and report a better error message.
claim

Discussion:
parse_async_move_order_incorrect = the order of `move` and `async` is incorrect .suggestion = try switching the order <ins> parse_at_dot_dot_in_struct_pattern = `@ ..` is not supported in struct patterns .suggestion = bind to each field separately or, if you don't need them, just remove `{$ident} @` parse_at_in_struct_pattern = Unexpected `@` in struct pattern .note = struct patterns use `field: pattern` syntax to bind to fields .help = consider replacing `new_name @ field_name` with `field_name: new_name` if that is what you intended </ins> parse_attr_after_generic = trailing attribute after generic parameter .label = attributes must go before parameters

} #[derive(Diagnostic)] <ins> #[diag(parse_at_dot_dot_in_struct_pattern)] pub(crate) struct AtDotDotInStructPattern { #[primary_span] pub span: Span, #[suggestion(code = "", style = "verbose", applicability = "machine-applicable")] pub remove: Span, pub ident: Ident, } #[derive(Diagnostic)] #[diag(parse_at_in_struct_pattern)] #[note] #[help] pub(crate) struct AtInStructPattern { #[primary_span] pub span: Span, } #[derive(Diagnostic)] </ins> #[diag(parse_dot_dot_dot_for_remaining_fields)] pub(crate) struct DotDotDotForRemainingFields { #[primary_span]

use super::{ForceCollect, Parser, PathStyle, Restrictions, Trailing, UsePreAttrPos}; use crate::errors::{ <del> self, AmbiguousRangePattern, DotDotDotForRemainingFields, DotDotDotRangeToPatternNotAllowed, DotDotDotRestPattern, EnumPatternInsteadOfIdentifier, ExpectedBindingLeftOfAt, ExpectedCommaAfterPatternField, GenericArgsInPatRequireTurbofishSyntax, InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern, ParenRangeSuggestion, PatternOnWrongSideOfAt, RemoveLet, RepeatedMutInPattern, SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg, TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedExpressionInPatternSugg, UnexpectedLifetimeInPattern, UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg, UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens, </del> <ins> self, AmbiguousRangePattern, AtDotDotInStructPattern, AtInStructPattern, DotDotDotForRemainingFields, DotDotDotRangeToPatternNotAllowed, DotDotDotRestPattern, EnumPatternInsteadOfIdentifier, ExpectedBindingLeftOfAt, ExpectedCommaAfterPatternField, GenericArgsInPatRequireTurbofishSyntax, InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern, ParenRangeSuggestion, PatternOnWrongSideOfAt, RemoveLet, RepeatedMutInPattern, SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg, TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedExpressionInPatternSugg, UnexpectedLifetimeInPattern, UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg, UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens, </ins> }; use crate::parser::expr::{could_be_unclosed_char_literal, DestructuredFloat}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};

/// Parses the fields of a struct-like pattern. fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec<PatField>, PatFieldsRest)> { <del> let mut fields = ThinVec::new(); </del> <ins> let mut fields: ThinVec<PatField> = ThinVec::new(); </ins> let mut etc = PatFieldsRest::None; let mut ate_comma = true; let mut delayed_err: Option<Diag<'a>> = None;

// check that a comma comes after every field if !ate_comma { <del> let mut err = self.dcx().create_err(ExpectedCommaAfterPatternField { span: self.token.span }); </del> <ins> let err = if self.token == token::At { let prev_field = fields .last() .expect("Unreachable on first iteration, not empty otherwise") .ident; self.report_misplaced_at_in_struct_pat(prev_field) } else { let mut err = self .dcx() .create_err(ExpectedCommaAfterPatternField { span: self.token.span }); self.recover_misplaced_pattern_modifiers(&fields, &mut err); err }; </ins> if let Some(delayed) = delayed_err { delayed.emit(); } <del> self.recover_misplaced_pattern_modifiers(&fields, &mut err); </del> return Err(err); } ate_comma = false;

Ok((fields, etc)) } <ins> #[deny(rustc::untranslatable_diagnostic)] fn report_misplaced_at_in_struct_pat(&self, prev_field: Ident) -> Diag<'a> { debug_assert_eq!(self.token, token::At); let span = prev_field.span.to(self.token.span); if let Some(dot_dot_span) = self.look_ahead(1, |t| if t == &token::DotDot { Some(t.span) } else { None }) { self.dcx().create_err(AtDotDotInStructPattern { span: span.to(dot_dot_span), remove: span.until(dot_dot_span), ident: prev_field, }) } else { self.dcx().create_err(AtInStructPattern { span: span }) } } </ins> /// If the user writes `S { ref field: name }` instead of `S { field: ref name }`, we suggest /// the correct code. fn recover_misplaced_pattern_modifiers(&self, fields: &ThinVec<PatField>, err: &mut Diag<'a>) {

<ins> struct Foo { field1: u8, field2: u8, } fn main() { let foo = Foo { field1: 1, field2: 2 }; let Foo { var @ field1, .. } = foo; //~ ERROR Unexpected `@` in struct pattern dbg!(var); //~ ERROR cannot find value `var` in this scope let Foo { field1: _, bar @ .. } = foo; //~ ERROR `@ ..` is not supported in struct patterns let Foo { bar @ .. } = foo; //~ ERROR `@ ..` is not supported in struct patterns let Foo { @ } = foo; //~ ERROR expected identifier, found `@` let Foo { @ .. } = foo; //~ ERROR expected identifier, found `@` } </ins>

<ins> error: Unexpected `@` in struct pattern --> $DIR/at-in-struct-patterns.rs:8:15 | LL |     let Foo { var @ field1, .. } = foo; |         ---   ^^^^^ |         | |         while parsing the fields for this pattern | = note: struct patterns use `field: pattern` syntax to bind to fields = help: consider replacing `new_name @ field_name` with `field_name: new_name` if that is what you intended error: `@ ..` is not supported in struct patterns --> $DIR/at-in-struct-patterns.rs:10:26 | LL |     let Foo { field1: _, bar @ .. } = foo; |         ---              ^^^^^^^^ |         | |         while parsing the fields for this pattern | help: bind to each field separately or, if you don't need them, just remove `bar @` | LL -     let Foo { field1: _, bar @ .. } = foo; LL +     let Foo { field1: _, .. } = foo; | error: `@ ..` is not supported in struct patterns --> $DIR/at-in-struct-patterns.rs:11:15 | LL |     let Foo { bar @ .. } = foo; |         ---   ^^^^^^^^ |         | |         while parsing the fields for this pattern | help: bind to each field separately or, if you don't need them, just remove `bar @` | LL -     let Foo { bar @ .. } = foo; LL +     let Foo { .. } = foo; | error: expected identifier, found `@` --> $DIR/at-in-struct-patterns.rs:12:15 | LL |     let Foo { @ } = foo; |         ---   ^ expected identifier |         | |         while parsing the fields for this pattern error: expected identifier, found `@` --> $DIR/at-in-struct-patterns.rs:13:15 | LL |     let Foo { @ .. } = foo; |         ---   ^ expected identifier |         | |         while parsing the fields for this pattern error[E0425]: cannot find value `var` in this scope --> $DIR/at-in-struct-patterns.rs:9:10 | LL |     dbg!(var); |          ^^^ not found in this scope | help: consider importing this function | LL + use std::env::var; | error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0425`. </ins>