@@ -834,9 +834,7 @@ impl<'a> Parser<'a> {
834834 hi = self . prev_span;
835835 ex = ExprKind :: Lit ( literal) ;
836836 }
837- None => {
838- return Err ( self . expected_expression_found( ) ) ;
839- }
837+ None => return Err ( self . expected_expression_found( ) ) ,
840838 }
841839 }
842840 }
@@ -846,37 +844,8 @@ impl<'a> Parser<'a> {
846844 // This match arm is a special-case of the `_` match arm below and
847845 // could be removed without changing functionality, but it's faster
848846 // to have it here, especially for programs with large constants.
849- token:: Literal ( _) => {
850- parse_lit ! ( )
851- }
852- token:: OpenDelim ( token:: Paren ) => {
853- let mut first = true ;
854- let parse_leading_attr_expr = |this : & mut Parser < ' a > | {
855- if first {
856- attrs. extend ( this. parse_inner_attributes ( ) ?) ;
857- first = false ;
858- }
859- this. parse_expr_catch_underscore ( )
860- } ;
861-
862- // (e) is parenthesized e
863- // (e,) is a tuple with only one field, e
864- let ( es, trailing_comma) =
865- match self . parse_paren_comma_seq ( parse_leading_attr_expr)
866- {
867- Ok ( x) => x,
868- Err ( err) => return Ok (
869- self . recover_seq_parse_error ( token:: Paren , lo, Err ( err) ) ,
870- ) ,
871- } ;
872-
873- hi = self . prev_span ;
874- ex = if es. len ( ) == 1 && !trailing_comma {
875- ExprKind :: Paren ( es. into_iter ( ) . nth ( 0 ) . unwrap ( ) )
876- } else {
877- ExprKind :: Tup ( es)
878- } ;
879- }
847+ token:: Literal ( _) => parse_lit ! ( ) ,
848+ token:: OpenDelim ( token:: Paren ) => return self . parse_tuple_parens_expr ( ) ,
880849 token:: OpenDelim ( token:: Brace ) => {
881850 return self . parse_block_expr ( None , lo, BlockCheckMode :: Default , attrs) ;
882851 }
@@ -1095,6 +1064,34 @@ impl<'a> Parser<'a> {
10951064 self . maybe_recover_from_bad_qpath ( expr, true )
10961065 }
10971066
1067+ fn parse_tuple_parens_expr ( & mut self ) -> PResult < ' a , P < Expr > > {
1068+ let lo = self . token . span ;
1069+ let mut first = true ;
1070+ let mut attrs = ThinVec :: new ( ) ;
1071+ let parse_leading_attr_expr = |p : & mut Self | {
1072+ if first {
1073+ // `(#![foo] a, b, ...)` is OK...
1074+ attrs = p. parse_inner_attributes ( ) ?. into ( ) ;
1075+ // ...but not `(a, #![foo] b, ...)`.
1076+ first = false ;
1077+ }
1078+ p. parse_expr_catch_underscore ( )
1079+ } ;
1080+ let ( es, trailing_comma) = match self . parse_paren_comma_seq ( parse_leading_attr_expr) {
1081+ Ok ( x) => x,
1082+ Err ( err) => return Ok ( self . recover_seq_parse_error ( token:: Paren , lo, Err ( err) ) ) ,
1083+ } ;
1084+ let kind = if es. len ( ) == 1 && !trailing_comma {
1085+ // `(e)` is parenthesized `e`.
1086+ ExprKind :: Paren ( es. into_iter ( ) . nth ( 0 ) . unwrap ( ) )
1087+ } else {
1088+ // `(e,)` is a tuple with only one field, `e`.
1089+ ExprKind :: Tup ( es)
1090+ } ;
1091+ let expr = self . mk_expr ( lo. to ( self . prev_span ) , kind, attrs) ;
1092+ self . maybe_recover_from_bad_qpath ( expr, true )
1093+ }
1094+
10981095 /// Returns a string literal if the next token is a string literal.
10991096 /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
11001097 /// and returns `None` if the next token is not literal at all.
0 commit comments