@@ -169,34 +169,8 @@ impl<'a> Parser<'a> {
169169 token:: DotDotDot | token:: DotDotEq | token:: DotDot => {
170170 self . parse_pat_range_starting_with_path ( lo, qself, path) ?
171171 }
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) ?,
200174 _ => PatKind :: Path ( qself, path) ,
201175 }
202176 } else {
@@ -481,6 +455,37 @@ impl<'a> Parser<'a> {
481455 Ok ( PatKind :: Ident ( binding_mode, ident, sub) )
482456 }
483457
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+
484489 /// Parses the fields of a struct-like pattern.
485490 fn parse_pat_fields ( & mut self ) -> PResult < ' a , ( Vec < Spanned < FieldPat > > , bool ) > {
486491 let mut fields = Vec :: new ( ) ;
@@ -515,17 +520,7 @@ impl<'a> Parser<'a> {
515520 etc = true ;
516521 let mut etc_sp = self . token . span ;
517522
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 ( ) ;
529524 self . bump ( ) ; // `..` || `...`
530525
531526 if self . token == token:: CloseDelim ( token:: Brace ) {
@@ -607,6 +602,23 @@ impl<'a> Parser<'a> {
607602 return Ok ( ( fields, etc) ) ;
608603 }
609604
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+
610622 fn parse_pat_field (
611623 & mut self ,
612624 lo : Span ,
0 commit comments