@@ -17,15 +17,16 @@ use thin_vec::{ThinVec, thin_vec};
17
17
18
18
use super :: { ForceCollect , Parser , PathStyle , Restrictions , Trailing , UsePreAttrPos } ;
19
19
use 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 ,
29
30
} ;
30
31
use crate :: parser:: expr:: { DestructuredFloat , could_be_unclosed_char_literal} ;
31
32
use crate :: { maybe_recover_from_interpolated_ty_qpath, maybe_whole} ;
@@ -1433,7 +1434,7 @@ impl<'a> Parser<'a> {
1433
1434
1434
1435
/// Parses the fields of a struct-like pattern.
1435
1436
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 ( ) ;
1437
1438
let mut etc = PatFieldsRest :: None ;
1438
1439
let mut ate_comma = true ;
1439
1440
let mut delayed_err: Option < Diag < ' a > > = None ;
@@ -1454,12 +1455,22 @@ impl<'a> Parser<'a> {
1454
1455
1455
1456
// check that a comma comes after every field
1456
1457
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
+ } ;
1459
1471
if let Some ( delayed) = delayed_err {
1460
1472
delayed. emit ( ) ;
1461
1473
}
1462
- self . recover_misplaced_pattern_modifiers ( & fields, & mut err) ;
1463
1474
return Err ( err) ;
1464
1475
}
1465
1476
ate_comma = false ;
@@ -1594,6 +1605,23 @@ impl<'a> Parser<'a> {
1594
1605
Ok ( ( fields, etc) )
1595
1606
}
1596
1607
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
+
1597
1625
/// If the user writes `S { ref field: name }` instead of `S { field: ref name }`, we suggest
1598
1626
/// the correct code.
1599
1627
fn recover_misplaced_pattern_modifiers ( & self , fields : & ThinVec < PatField > , err : & mut Diag < ' a > ) {
0 commit comments