@@ -3612,17 +3612,20 @@ impl<'a> Parser<'a> {
36123612 self . token . is_keyword ( kw:: Async ) && self . is_gen_block ( kw:: Gen , 1 )
36133613 }
36143614
3615+ fn is_likely_struct_lit ( & self ) -> bool {
3616+ // `{ ident, ` and `{ ident: ` cannot start a block.
3617+ self . look_ahead ( 1 , |t| t. is_ident ( ) )
3618+ && self . look_ahead ( 2 , |t| t == & token:: Comma || t == & token:: Colon )
3619+ }
3620+
36153621 fn maybe_parse_struct_expr (
36163622 & mut self ,
36173623 qself : & Option < Box < ast:: QSelf > > ,
36183624 path : & ast:: Path ,
36193625 ) -> Option < PResult < ' a , Box < Expr > > > {
36203626 let struct_allowed = !self . restrictions . contains ( Restrictions :: NO_STRUCT_LITERAL ) ;
3621- let is_ident = self . look_ahead ( 1 , |t| t. is_ident ( ) ) ;
3622- let is_comma = self . look_ahead ( 2 , |t| t == & token:: Comma ) ;
3623- let is_colon = self . look_ahead ( 2 , |t| t == & token:: Colon ) ;
3624- match ( struct_allowed, is_ident, is_comma, is_colon) {
3625- ( false , true , true , _) | ( false , true , _, true ) => {
3627+ match ( struct_allowed, self . is_likely_struct_lit ( ) ) {
3628+ ( false , true ) => {
36263629 // We have something like `match foo { bar,` or `match foo { bar:`, which means the
36273630 // user might have meant to write a struct literal as part of the `match`
36283631 // discriminant.
@@ -3651,15 +3654,15 @@ impl<'a> Parser<'a> {
36513654 }
36523655 }
36533656 }
3654- ( true , _, _ , _ ) => {
3657+ ( true , _) => {
36553658 // A struct is accepted here, try to parse it and rely on `parse_expr_struct` for
36563659 // any kind of recovery.
36573660 if let Err ( err) = self . expect ( exp ! ( OpenBrace ) ) {
36583661 return Some ( Err ( err) ) ;
36593662 }
36603663 Some ( self . parse_expr_struct ( qself. clone ( ) , path. clone ( ) , true ) )
36613664 }
3662- ( false , _ , _ , _ ) => None ,
3665+ ( false , false ) => None ,
36633666 }
36643667 }
36653668
0 commit comments