@@ -105,6 +105,12 @@ pub enum ParsePub {
105105 No ,
106106}
107107
108+ #[ derive( Clone , Copy , PartialEq ) ]
109+ pub enum SemiColonMode {
110+ Break ,
111+ Ignore ,
112+ }
113+
108114/// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
109115/// dropped into the token stream, which happens while parsing the result of
110116/// macro expansion). Placement of these is not as complex as I feared it would
@@ -843,7 +849,10 @@ impl<'a> Parser<'a> {
843849 /// Eat and discard tokens until one of `kets` is encountered. Respects token trees,
844850 /// passes through any errors encountered. Used for error recovery.
845851 pub fn eat_to_tokens ( & mut self , kets : & [ & token:: Token ] ) {
846- self . parse_seq_to_before_tokens ( kets, seq_sep_none ( ) , |p| p. parse_token_tree ( ) ) ;
852+ self . parse_seq_to_before_tokens ( kets,
853+ seq_sep_none ( ) ,
854+ |p| p. parse_token_tree ( ) ,
855+ |mut e| e. cancel ( ) ) ;
847856 }
848857
849858 /// Parse a sequence, including the closing delimiter. The function
@@ -871,15 +880,18 @@ impl<'a> Parser<'a> {
871880 -> Vec < T >
872881 where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
873882 {
874- self . parse_seq_to_before_tokens ( & [ ket] , sep, f)
883+ self . parse_seq_to_before_tokens ( & [ ket] , sep, f, | mut e| e . emit ( ) )
875884 }
876885
877- pub fn parse_seq_to_before_tokens < T , F > ( & mut self ,
886+ // `fe` is an error handler.
887+ fn parse_seq_to_before_tokens < T , F , Fe > ( & mut self ,
878888 kets : & [ & token:: Token ] ,
879889 sep : SeqSep ,
880- mut f : F )
890+ mut f : F ,
891+ mut fe : Fe )
881892 -> Vec < T >
882893 where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
894+ Fe : FnMut ( DiagnosticBuilder )
883895 {
884896 let mut first: bool = true ;
885897 let mut v = vec ! ( ) ;
@@ -889,8 +901,8 @@ impl<'a> Parser<'a> {
889901 if first {
890902 first = false ;
891903 } else {
892- if let Err ( mut e) = self . expect ( t) {
893- e . emit ( ) ;
904+ if let Err ( e) = self . expect ( t) {
905+ fe ( e ) ;
894906 break ;
895907 }
896908 }
@@ -903,8 +915,8 @@ impl<'a> Parser<'a> {
903915
904916 match f ( self ) {
905917 Ok ( t) => v. push ( t) ,
906- Err ( mut e) => {
907- e . emit ( ) ;
918+ Err ( e) => {
919+ fe ( e ) ;
908920 break ;
909921 }
910922 }
@@ -1263,7 +1275,7 @@ impl<'a> Parser<'a> {
12631275 break ;
12641276 }
12651277 }
1266-
1278+
12671279 return Err ( e) ;
12681280 }
12691281 } ;
@@ -2339,14 +2351,37 @@ impl<'a> Parser<'a> {
23392351
23402352 while self . token != token:: CloseDelim ( token:: Brace ) {
23412353 if self . eat ( & token:: DotDot ) {
2342- base = Some ( try!( self . parse_expr ( ) ) ) ;
2354+ match self . parse_expr ( ) {
2355+ Ok ( e) => {
2356+ base = Some ( e) ;
2357+ }
2358+ Err ( mut e) => {
2359+ e. emit ( ) ;
2360+ self . recover_stmt ( ) ;
2361+ }
2362+ }
23432363 break ;
23442364 }
23452365
2346- fields. push ( try!( self . parse_field ( ) ) ) ;
2347- try!( self . commit_expr ( & fields. last ( ) . unwrap ( ) . expr ,
2348- & [ token:: Comma ] ,
2349- & [ token:: CloseDelim ( token:: Brace ) ] ) ) ;
2366+ match self . parse_field ( ) {
2367+ Ok ( f) => fields. push ( f) ,
2368+ Err ( mut e) => {
2369+ e. emit ( ) ;
2370+ self . recover_stmt ( ) ;
2371+ break ;
2372+ }
2373+ }
2374+
2375+ match self . commit_expr ( & fields. last ( ) . unwrap ( ) . expr ,
2376+ & [ token:: Comma ] ,
2377+ & [ token:: CloseDelim ( token:: Brace ) ] ) {
2378+ Ok ( ( ) ) => { }
2379+ Err ( mut e) => {
2380+ e. emit ( ) ;
2381+ self . recover_stmt ( ) ;
2382+ break ;
2383+ }
2384+ }
23502385 }
23512386
23522387 hi = self . span . hi ;
@@ -2748,6 +2783,7 @@ impl<'a> Parser<'a> {
27482783 if let Some ( & sp) = self . open_braces . last ( ) {
27492784 err. span_note ( sp, "unclosed delimiter" ) ;
27502785 } ;
2786+
27512787 Err ( err)
27522788 } ,
27532789 /* we ought to allow different depths of unquotation */
@@ -3195,8 +3231,8 @@ impl<'a> Parser<'a> {
31953231 fn parse_match_expr ( & mut self , attrs : ThinAttributes ) -> PResult < ' a , P < Expr > > {
31963232 let match_span = self . last_span ;
31973233 let lo = self . last_span . lo ;
3198- let discriminant = try!( self . parse_expr_res (
3199- Restrictions :: RESTRICTION_NO_STRUCT_LITERAL , None ) ) ;
3234+ let discriminant = try!( self . parse_expr_res ( Restrictions :: RESTRICTION_NO_STRUCT_LITERAL ,
3235+ None ) ) ;
32003236 if let Err ( mut e) = self . commit_expr_expecting ( & discriminant,
32013237 token:: OpenDelim ( token:: Brace ) ) {
32023238 if self . token == token:: Token :: Semi {
@@ -3208,7 +3244,19 @@ impl<'a> Parser<'a> {
32083244 try!( self . parse_inner_attributes ( ) ) . into_thin_attrs ( ) ) ;
32093245 let mut arms: Vec < Arm > = Vec :: new ( ) ;
32103246 while self . token != token:: CloseDelim ( token:: Brace ) {
3211- arms. push ( try!( self . parse_arm ( ) ) ) ;
3247+ match self . parse_arm ( ) {
3248+ Ok ( arm) => arms. push ( arm) ,
3249+ Err ( mut e) => {
3250+ // Recover by skipping to the end of the block.
3251+ e. emit ( ) ;
3252+ self . recover_stmt ( ) ;
3253+ let hi = self . span . hi ;
3254+ if self . token == token:: CloseDelim ( token:: Brace ) {
3255+ self . bump ( ) ;
3256+ }
3257+ return Ok ( self . mk_expr ( lo, hi, ExprMatch ( discriminant, arms) , attrs) ) ;
3258+ }
3259+ }
32123260 }
32133261 let hi = self . span . hi ;
32143262 self . bump ( ) ;
@@ -3566,7 +3614,11 @@ impl<'a> Parser<'a> {
35663614 }
35673615 // Parse struct pattern
35683616 self . bump ( ) ;
3569- let ( fields, etc) = try!( self . parse_pat_fields ( ) ) ;
3617+ let ( fields, etc) = self . parse_pat_fields ( ) . unwrap_or_else ( |mut e| {
3618+ e. emit ( ) ;
3619+ self . recover_stmt ( ) ;
3620+ ( vec ! [ ] , false )
3621+ } ) ;
35703622 self . bump ( ) ;
35713623 pat = PatKind :: Struct ( path, fields, etc) ;
35723624 }
@@ -3720,10 +3772,72 @@ impl<'a> Parser<'a> {
37203772
37213773 /// Parse a statement. may include decl.
37223774 pub fn parse_stmt ( & mut self ) -> PResult < ' a , Option < Stmt > > {
3723- Ok ( try!( self . parse_stmt_ ( ) ) )
3775+ Ok ( self . parse_stmt_ ( ) . map ( P ) )
3776+ }
3777+
3778+ // Eat tokens until we can be relatively sure we reached the end of the
3779+ // statement. This is something of a best-effort heuristic.
3780+ //
3781+ // We terminate when we find an unmatched `}` (without consuming it).
3782+ fn recover_stmt ( & mut self ) {
3783+ self . recover_stmt_ ( SemiColonMode :: Ignore )
3784+ }
3785+ // If `break_on_semi` is `Break`, then we will stop consuming tokens after
3786+ // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
3787+ // approximate - it can mean we break too early due to macros, but that
3788+ // shoud only lead to sub-optimal recovery, not inaccurate parsing).
3789+ fn recover_stmt_ ( & mut self , break_on_semi : SemiColonMode ) {
3790+ let mut brace_depth = 0 ;
3791+ let mut bracket_depth = 0 ;
3792+ loop {
3793+ match self . token {
3794+ token:: OpenDelim ( token:: DelimToken :: Brace ) => {
3795+ brace_depth += 1 ;
3796+ self . bump ( ) ;
3797+ }
3798+ token:: OpenDelim ( token:: DelimToken :: Bracket ) => {
3799+ bracket_depth += 1 ;
3800+ self . bump ( ) ;
3801+ }
3802+ token:: CloseDelim ( token:: DelimToken :: Brace ) => {
3803+ if brace_depth == 0 {
3804+ return ;
3805+ }
3806+ brace_depth -= 1 ;
3807+ self . bump ( ) ;
3808+ }
3809+ token:: CloseDelim ( token:: DelimToken :: Bracket ) => {
3810+ bracket_depth -= 1 ;
3811+ if bracket_depth < 0 {
3812+ bracket_depth = 0 ;
3813+ }
3814+ self . bump ( ) ;
3815+ }
3816+ token:: Eof => return ,
3817+ token:: Semi => {
3818+ self . bump ( ) ;
3819+ if break_on_semi == SemiColonMode :: Break &&
3820+ brace_depth == 0 &&
3821+ bracket_depth == 0 {
3822+ return ;
3823+ }
3824+ }
3825+ _ => {
3826+ self . bump ( )
3827+ }
3828+ }
3829+ }
37243830 }
37253831
3726- fn parse_stmt_ ( & mut self ) -> PResult < ' a , Option < Stmt > > {
3832+ fn parse_stmt_ ( & mut self ) -> Option < Stmt > {
3833+ self . parse_stmt_without_recovery ( ) . unwrap_or_else ( |mut e| {
3834+ e. emit ( ) ;
3835+ self . recover_stmt_ ( SemiColonMode :: Break ) ;
3836+ None
3837+ } )
3838+ }
3839+
3840+ fn parse_stmt_without_recovery ( & mut self ) -> PResult < ' a , Option < Stmt > > {
37273841 maybe_whole ! ( Some deref self , NtStmt ) ;
37283842
37293843 let attrs = try!( self . parse_outer_attributes ( ) ) ;
@@ -3879,7 +3993,7 @@ impl<'a> Parser<'a> {
38793993 let lo = self . span . lo ;
38803994 try!( self . expect ( & token:: OpenDelim ( token:: Brace ) ) ) ;
38813995 Ok ( ( try!( self . parse_inner_attributes ( ) ) ,
3882- try!( self . parse_block_tail ( lo, BlockCheckMode :: Default ) ) ) )
3996+ try!( self . parse_block_tail ( lo, BlockCheckMode :: Default ) ) ) )
38833997 }
38843998
38853999 /// Parse the rest of a block expression or function body
@@ -3889,7 +4003,7 @@ impl<'a> Parser<'a> {
38894003 let mut expr = None ;
38904004
38914005 while !self . eat ( & token:: CloseDelim ( token:: Brace ) ) {
3892- let Spanned { node, span} = if let Some ( s) = try! ( self . parse_stmt_ ( ) ) {
4006+ let Spanned { node, span} = if let Some ( s) = self . parse_stmt_ ( ) {
38934007 s
38944008 } else {
38954009 // Found only `;` or `}`.
@@ -3974,17 +4088,21 @@ impl<'a> Parser<'a> {
39744088 } ) )
39754089 }
39764090
3977- fn handle_expression_like_statement (
3978- & mut self ,
3979- e : P < Expr > ,
3980- span : Span ,
3981- stmts : & mut Vec < Stmt > ,
3982- last_block_expr : & mut Option < P < Expr > > ) -> PResult < ' a , ( ) > {
4091+ fn handle_expression_like_statement ( & mut self ,
4092+ e : P < Expr > ,
4093+ span : Span ,
4094+ stmts : & mut Vec < Stmt > ,
4095+ last_block_expr : & mut Option < P < Expr > > )
4096+ -> PResult < ' a , ( ) > {
39834097 // expression without semicolon
39844098 if classify:: expr_requires_semi_to_be_stmt ( & e) {
39854099 // Just check for errors and recover; do not eat semicolon yet.
3986- try!( self . commit_stmt ( & [ ] ,
3987- & [ token:: Semi , token:: CloseDelim ( token:: Brace ) ] ) ) ;
4100+ if let Err ( mut e) =
4101+ self . commit_stmt ( & [ ] , & [ token:: Semi , token:: CloseDelim ( token:: Brace ) ] )
4102+ {
4103+ e. emit ( ) ;
4104+ self . recover_stmt ( ) ;
4105+ }
39884106 }
39894107
39904108 match self . token {
@@ -4381,13 +4499,13 @@ impl<'a> Parser<'a> {
43814499 }
43824500 ) ) ;
43834501
4502+ let args: Vec < _ > = args. into_iter ( ) . filter_map ( |x| x) . collect ( ) ;
4503+
43844504 if variadic && args. is_empty ( ) {
43854505 self . span_err ( sp,
43864506 "variadic function must be declared with at least one named argument" ) ;
43874507 }
43884508
4389- let args = args. into_iter ( ) . filter_map ( |x| x) . collect ( ) ;
4390-
43914509 Ok ( ( args, variadic) )
43924510 }
43934511
0 commit comments