@@ -169,34 +169,8 @@ impl<'a> Parser<'a> {
169
169
token:: DotDotDot | token:: DotDotEq | token:: DotDot => {
170
170
self . parse_pat_range_starting_with_path ( lo, qself, path) ?
171
171
}
172
- token:: OpenDelim ( token:: Brace ) => {
173
- if qself. is_some ( ) {
174
- let msg = "unexpected `{` after qualified path" ;
175
- let mut err = self . fatal ( msg) ;
176
- err. span_label ( self . token . span , msg) ;
177
- return Err ( err) ;
178
- }
179
- // Parse struct pattern
180
- self . bump ( ) ;
181
- let ( fields, etc) = self . parse_pat_fields ( ) . unwrap_or_else ( |mut e| {
182
- e. emit ( ) ;
183
- self . recover_stmt ( ) ;
184
- ( vec ! [ ] , true )
185
- } ) ;
186
- self . bump ( ) ;
187
- PatKind :: Struct ( path, fields, etc)
188
- }
189
- token:: OpenDelim ( token:: Paren ) => {
190
- if qself. is_some ( ) {
191
- let msg = "unexpected `(` after qualified path" ;
192
- let mut err = self . fatal ( msg) ;
193
- err. span_label ( self . token . span , msg) ;
194
- return Err ( err) ;
195
- }
196
- // Parse tuple struct or enum pattern
197
- let ( fields, _) = self . parse_paren_comma_seq ( |p| p. parse_pat ( None ) ) ?;
198
- PatKind :: TupleStruct ( path, fields)
199
- }
172
+ token:: OpenDelim ( token:: Brace ) => self . parse_pat_struct ( qself, path) ?,
173
+ token:: OpenDelim ( token:: Paren ) => self . parse_pat_tuple_struct ( qself, path) ?,
200
174
_ => PatKind :: Path ( qself, path) ,
201
175
}
202
176
} else {
@@ -481,6 +455,37 @@ impl<'a> Parser<'a> {
481
455
Ok ( PatKind :: Ident ( binding_mode, ident, sub) )
482
456
}
483
457
458
+ /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
459
+ fn parse_pat_struct ( & mut self , qself : Option < QSelf > , path : Path ) -> PResult < ' a , PatKind > {
460
+ if qself. is_some ( ) {
461
+ let msg = "unexpected `{` after qualified path" ;
462
+ let mut err = self . fatal ( msg) ;
463
+ err. span_label ( self . token . span , msg) ;
464
+ return Err ( err) ;
465
+ }
466
+
467
+ self . bump ( ) ;
468
+ let ( fields, etc) = self . parse_pat_fields ( ) . unwrap_or_else ( |mut e| {
469
+ e. emit ( ) ;
470
+ self . recover_stmt ( ) ;
471
+ ( vec ! [ ] , true )
472
+ } ) ;
473
+ self . bump ( ) ;
474
+ Ok ( PatKind :: Struct ( path, fields, etc) )
475
+ }
476
+
477
+ /// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`).
478
+ fn parse_pat_tuple_struct ( & mut self , qself : Option < QSelf > , path : Path ) -> PResult < ' a , PatKind > {
479
+ if qself. is_some ( ) {
480
+ let msg = "unexpected `(` after qualified path" ;
481
+ let mut err = self . fatal ( msg) ;
482
+ err. span_label ( self . token . span , msg) ;
483
+ return Err ( err) ;
484
+ }
485
+ let ( fields, _) = self . parse_paren_comma_seq ( |p| p. parse_pat ( None ) ) ?;
486
+ Ok ( PatKind :: TupleStruct ( path, fields) )
487
+ }
488
+
484
489
/// Parses the fields of a struct-like pattern.
485
490
fn parse_pat_fields ( & mut self ) -> PResult < ' a , ( Vec < Spanned < FieldPat > > , bool ) > {
486
491
let mut fields = Vec :: new ( ) ;
@@ -515,17 +520,7 @@ impl<'a> Parser<'a> {
515
520
etc = true ;
516
521
let mut etc_sp = self . token . span ;
517
522
518
- if self . token == token:: DotDotDot { // Issue #46718
519
- // Accept `...` as if it were `..` to avoid further errors
520
- self . struct_span_err ( self . token . span , "expected field pattern, found `...`" )
521
- . span_suggestion (
522
- self . token . span ,
523
- "to omit remaining fields, use one fewer `.`" ,
524
- ".." . to_owned ( ) ,
525
- Applicability :: MachineApplicable
526
- )
527
- . emit ( ) ;
528
- }
523
+ self . recover_one_fewer_dotdot ( ) ;
529
524
self . bump ( ) ; // `..` || `...`
530
525
531
526
if self . token == token:: CloseDelim ( token:: Brace ) {
@@ -607,6 +602,23 @@ impl<'a> Parser<'a> {
607
602
return Ok ( ( fields, etc) ) ;
608
603
}
609
604
605
+ /// Recover on `...` as if it were `..` to avoid further errors.
606
+ /// See issue #46718.
607
+ fn recover_one_fewer_dotdot ( & self ) {
608
+ if self . token != token:: DotDotDot {
609
+ return ;
610
+ }
611
+
612
+ self . struct_span_err ( self . token . span , "expected field pattern, found `...`" )
613
+ . span_suggestion (
614
+ self . token . span ,
615
+ "to omit remaining fields, use one fewer `.`" ,
616
+ ".." . to_owned ( ) ,
617
+ Applicability :: MachineApplicable
618
+ )
619
+ . emit ( ) ;
620
+ }
621
+
610
622
fn parse_pat_field (
611
623
& mut self ,
612
624
lo : Span ,
0 commit comments