@@ -1415,8 +1415,8 @@ impl<'a> Parser<'a> {
1415
1415
self . bump ( ) ;
1416
1416
( thin_vec ! [ ] , false )
1417
1417
} else {
1418
- self . parse_delim_comma_seq ( Delimiter :: Brace , |p| p. parse_enum_variant ( ) ) . map_err (
1419
- |mut err| {
1418
+ self . parse_delim_comma_seq ( Delimiter :: Brace , |p| p. parse_enum_variant ( id . span ) )
1419
+ . map_err ( |mut err| {
1420
1420
err. span_label ( id. span , "while parsing this enum" ) ;
1421
1421
if self . token == token:: Colon {
1422
1422
let snapshot = self . create_snapshot_for_diagnostic ( ) ;
@@ -1436,17 +1436,17 @@ impl<'a> Parser<'a> {
1436
1436
}
1437
1437
self . restore_snapshot ( snapshot) ;
1438
1438
}
1439
- self . recover_stmt ( ) ;
1439
+ self . eat_to_tokens ( & [ & token:: CloseDelim ( Delimiter :: Brace ) ] ) ;
1440
+ self . bump ( ) ; // }
1440
1441
err
1441
- } ,
1442
- ) ?
1442
+ } ) ?
1443
1443
} ;
1444
1444
1445
1445
let enum_definition = EnumDef { variants : variants. into_iter ( ) . flatten ( ) . collect ( ) } ;
1446
1446
Ok ( ( id, ItemKind :: Enum ( enum_definition, generics) ) )
1447
1447
}
1448
1448
1449
- fn parse_enum_variant ( & mut self ) -> PResult < ' a , Option < Variant > > {
1449
+ fn parse_enum_variant ( & mut self , span : Span ) -> PResult < ' a , Option < Variant > > {
1450
1450
self . recover_diff_marker ( ) ;
1451
1451
let variant_attrs = self . parse_outer_attributes ( ) ?;
1452
1452
self . recover_diff_marker ( ) ;
@@ -1476,10 +1476,37 @@ impl<'a> Parser<'a> {
1476
1476
let struct_def = if this. check ( & token:: OpenDelim ( Delimiter :: Brace ) ) {
1477
1477
// Parse a struct variant.
1478
1478
let ( fields, recovered) =
1479
- this. parse_record_struct_body ( "struct" , ident. span , false ) ?;
1479
+ match this. parse_record_struct_body ( "struct" , ident. span , false ) {
1480
+ Ok ( ( fields, recovered) ) => ( fields, recovered) ,
1481
+ Err ( mut err) => {
1482
+ if this. token == token:: Colon {
1483
+ // We handle `enum` to `struct` suggestion in the caller.
1484
+ return Err ( err) ;
1485
+ }
1486
+ this. eat_to_tokens ( & [ & token:: CloseDelim ( Delimiter :: Brace ) ] ) ;
1487
+ this. bump ( ) ; // }
1488
+ err. span_label ( span, "while parsing this enum" ) ;
1489
+ err. emit ( ) ;
1490
+ ( thin_vec ! [ ] , true )
1491
+ }
1492
+ } ;
1480
1493
VariantData :: Struct ( fields, recovered)
1481
1494
} else if this. check ( & token:: OpenDelim ( Delimiter :: Parenthesis ) ) {
1482
- VariantData :: Tuple ( this. parse_tuple_struct_body ( ) ?, DUMMY_NODE_ID )
1495
+ let body = match this. parse_tuple_struct_body ( ) {
1496
+ Ok ( body) => body,
1497
+ Err ( mut err) => {
1498
+ if this. token == token:: Colon {
1499
+ // We handle `enum` to `struct` suggestion in the caller.
1500
+ return Err ( err) ;
1501
+ }
1502
+ this. eat_to_tokens ( & [ & token:: CloseDelim ( Delimiter :: Parenthesis ) ] ) ;
1503
+ this. bump ( ) ; // )
1504
+ err. span_label ( span, "while parsing this enum" ) ;
1505
+ err. emit ( ) ;
1506
+ thin_vec ! [ ]
1507
+ }
1508
+ } ;
1509
+ VariantData :: Tuple ( body, DUMMY_NODE_ID )
1483
1510
} else {
1484
1511
VariantData :: Unit ( DUMMY_NODE_ID )
1485
1512
} ;
0 commit comments