@@ -17,15 +17,16 @@ use thin_vec::{ThinVec, thin_vec};
1717
1818use super :: { ForceCollect , Parser , PathStyle , Restrictions , Trailing , UsePreAttrPos } ;
1919use crate :: errors:: {
20- self , AmbiguousRangePattern , DotDotDotForRemainingFields , DotDotDotRangeToPatternNotAllowed ,
21- DotDotDotRestPattern , EnumPatternInsteadOfIdentifier , ExpectedBindingLeftOfAt ,
22- ExpectedCommaAfterPatternField , GenericArgsInPatRequireTurbofishSyntax ,
23- InclusiveRangeExtraEquals , InclusiveRangeMatchArrow , InclusiveRangeNoEnd , InvalidMutInPattern ,
24- ParenRangeSuggestion , PatternOnWrongSideOfAt , RemoveLet , RepeatedMutInPattern ,
25- SwitchRefBoxOrder , TopLevelOrPatternNotAllowed , TopLevelOrPatternNotAllowedSugg ,
26- TrailingVertNotAllowed , UnexpectedExpressionInPattern , UnexpectedExpressionInPatternSugg ,
27- UnexpectedLifetimeInPattern , UnexpectedParenInRangePat , UnexpectedParenInRangePatSugg ,
28- UnexpectedVertVertBeforeFunctionParam , UnexpectedVertVertInPattern , WrapInParens ,
20+ self , AmbiguousRangePattern , AtDotDotInStructPattern , AtInStructPattern ,
21+ DotDotDotForRemainingFields , DotDotDotRangeToPatternNotAllowed , DotDotDotRestPattern ,
22+ EnumPatternInsteadOfIdentifier , ExpectedBindingLeftOfAt , ExpectedCommaAfterPatternField ,
23+ GenericArgsInPatRequireTurbofishSyntax , InclusiveRangeExtraEquals , InclusiveRangeMatchArrow ,
24+ InclusiveRangeNoEnd , InvalidMutInPattern , ParenRangeSuggestion , PatternOnWrongSideOfAt ,
25+ RemoveLet , RepeatedMutInPattern , SwitchRefBoxOrder , TopLevelOrPatternNotAllowed ,
26+ TopLevelOrPatternNotAllowedSugg , TrailingVertNotAllowed , UnexpectedExpressionInPattern ,
27+ UnexpectedExpressionInPatternSugg , UnexpectedLifetimeInPattern , UnexpectedParenInRangePat ,
28+ UnexpectedParenInRangePatSugg , UnexpectedVertVertBeforeFunctionParam ,
29+ UnexpectedVertVertInPattern , WrapInParens ,
2930} ;
3031use crate :: parser:: expr:: { DestructuredFloat , could_be_unclosed_char_literal} ;
3132use crate :: { maybe_recover_from_interpolated_ty_qpath, maybe_whole} ;
@@ -1433,7 +1434,7 @@ impl<'a> Parser<'a> {
14331434
14341435 /// Parses the fields of a struct-like pattern.
14351436 fn parse_pat_fields ( & mut self ) -> PResult < ' a , ( ThinVec < PatField > , PatFieldsRest ) > {
1436- let mut fields = ThinVec :: new ( ) ;
1437+ let mut fields: ThinVec < PatField > = ThinVec :: new ( ) ;
14371438 let mut etc = PatFieldsRest :: None ;
14381439 let mut ate_comma = true ;
14391440 let mut delayed_err: Option < Diag < ' a > > = None ;
@@ -1454,12 +1455,22 @@ impl<'a> Parser<'a> {
14541455
14551456 // check that a comma comes after every field
14561457 if !ate_comma {
1457- let mut err =
1458- self . dcx ( ) . create_err ( ExpectedCommaAfterPatternField { span : self . token . span } ) ;
1458+ let err = if self . token == token:: At {
1459+ let prev_field = fields
1460+ . last ( )
1461+ . expect ( "Unreachable on first iteration, not empty otherwise" )
1462+ . ident ;
1463+ self . report_misplaced_at_in_struct_pat ( prev_field)
1464+ } else {
1465+ let mut err = self
1466+ . dcx ( )
1467+ . create_err ( ExpectedCommaAfterPatternField { span : self . token . span } ) ;
1468+ self . recover_misplaced_pattern_modifiers ( & fields, & mut err) ;
1469+ err
1470+ } ;
14591471 if let Some ( delayed) = delayed_err {
14601472 delayed. emit ( ) ;
14611473 }
1462- self . recover_misplaced_pattern_modifiers ( & fields, & mut err) ;
14631474 return Err ( err) ;
14641475 }
14651476 ate_comma = false ;
@@ -1594,6 +1605,23 @@ impl<'a> Parser<'a> {
15941605 Ok ( ( fields, etc) )
15951606 }
15961607
1608+ #[ deny( rustc:: untranslatable_diagnostic) ]
1609+ fn report_misplaced_at_in_struct_pat ( & self , prev_field : Ident ) -> Diag < ' a > {
1610+ debug_assert_eq ! ( self . token, token:: At ) ;
1611+ let span = prev_field. span . to ( self . token . span ) ;
1612+ if let Some ( dot_dot_span) =
1613+ self . look_ahead ( 1 , |t| if t == & token:: DotDot { Some ( t. span ) } else { None } )
1614+ {
1615+ self . dcx ( ) . create_err ( AtDotDotInStructPattern {
1616+ span : span. to ( dot_dot_span) ,
1617+ remove : span. until ( dot_dot_span) ,
1618+ ident : prev_field,
1619+ } )
1620+ } else {
1621+ self . dcx ( ) . create_err ( AtInStructPattern { span : span } )
1622+ }
1623+ }
1624+
15971625 /// If the user writes `S { ref field: name }` instead of `S { field: ref name }`, we suggest
15981626 /// the correct code.
15991627 fn recover_misplaced_pattern_modifiers ( & self , fields : & ThinVec < PatField > , err : & mut Diag < ' a > ) {
0 commit comments