@@ -91,24 +91,29 @@ impl<'a> Parser<'a> {
9191 self . parse_expr_res ( Restrictions :: empty ( ) , None )
9292 }
9393
94+ fn parse_expr_catch_underscore ( & mut self ) -> PResult < ' a , P < Expr > > {
95+ match self . parse_expr ( ) {
96+ Ok ( expr) => Ok ( expr) ,
97+ Err ( mut err) => match self . token . kind {
98+ token:: Ident ( name, false )
99+ if name == kw:: Underscore && self . look_ahead ( 1 , |t| {
100+ t == & token:: Comma
101+ } ) => {
102+ // Special-case handling of `foo(_, _, _)`
103+ err. emit ( ) ;
104+ let sp = self . token . span ;
105+ self . bump ( ) ;
106+ Ok ( self . mk_expr ( sp, ExprKind :: Err , ThinVec :: new ( ) ) )
107+ }
108+ _ => Err ( err) ,
109+ } ,
110+ }
111+ }
112+
113+ /// Parses a sequence of expressions bounded by parentheses.
94114 fn parse_paren_expr_seq ( & mut self ) -> PResult < ' a , Vec < P < Expr > > > {
95115 self . parse_paren_comma_seq ( |p| {
96- match p. parse_expr ( ) {
97- Ok ( expr) => Ok ( expr) ,
98- Err ( mut err) => match p. token . kind {
99- token:: Ident ( name, false )
100- if name == kw:: Underscore && p. look_ahead ( 1 , |t| {
101- t == & token:: Comma
102- } ) => {
103- // Special-case handling of `foo(_, _, _)`
104- err. emit ( ) ;
105- let sp = p. token . span ;
106- p. bump ( ) ;
107- Ok ( p. mk_expr ( sp, ExprKind :: Err , ThinVec :: new ( ) ) )
108- }
109- _ => Err ( err) ,
110- } ,
111- }
116+ p. parse_expr_catch_underscore ( )
112117 } ) . map ( |( r, _) | r)
113118 }
114119
@@ -845,51 +850,25 @@ impl<'a> Parser<'a> {
845850 parse_lit ! ( )
846851 }
847852 token:: OpenDelim ( token:: Paren ) => {
848- self . bump ( ) ;
849-
850- attrs. extend ( self . parse_inner_attributes ( ) ?) ;
851-
852- // `(e)` is parenthesized `e`.
853- // `(e,)` is a tuple with only one field, `e`.
854- let mut es = vec ! [ ] ;
855- let mut trailing_comma = false ;
856- let mut recovered = false ;
857- while self . token != token:: CloseDelim ( token:: Paren ) {
858- es. push ( match self . parse_expr ( ) {
859- Ok ( es) => es,
860- Err ( mut err) => {
861- // Recover from parse error in tuple list.
862- match self . token . kind {
863- token:: Ident ( name, false )
864- if name == kw:: Underscore && self . look_ahead ( 1 , |t| {
865- t == & token:: Comma
866- } ) => {
867- // Special-case handling of `Foo<(_, _, _)>`
868- err. emit ( ) ;
869- let sp = self . token . span ;
870- self . bump ( ) ;
871- self . mk_expr ( sp, ExprKind :: Err , ThinVec :: new ( ) )
872- }
873- _ => return Ok (
874- self . recover_seq_parse_error ( token:: Paren , lo, Err ( err) ) ,
875- ) ,
876- }
877- }
878- } ) ;
879- recovered = self . expect_one_of (
880- & [ ] ,
881- & [ token:: Comma , token:: CloseDelim ( token:: Paren ) ] ,
882- ) ?;
883- if self . eat ( & token:: Comma ) {
884- trailing_comma = true ;
885- } else {
886- trailing_comma = false ;
887- break ;
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 ;
888858 }
889- }
890- if !recovered {
891- self . bump ( ) ;
892- }
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+ } ;
893872
894873 hi = self . prev_span ;
895874 ex = if es. len ( ) == 1 && !trailing_comma {
0 commit comments