@@ -268,8 +268,8 @@ pub struct Parser<'a> {
268268    /// Used to determine the path to externally loaded source files 
269269pub  filename :  Option < String > , 
270270    pub  mod_path_stack :  Vec < InternedString > , 
271-     /// Stack of spans of  open delimiters. Used for error message. 
272- pub  open_braces :  Vec < Span > , 
271+     /// Stack of open delimiters and their spans . Used for error message. 
272+ pub  open_braces :  Vec < ( token :: DelimToken ,   Span ) > , 
273273    /// Flag if this parser "owns" the directory that it is currently parsing 
274274/// in. This will affect how nested files are looked up. 
275275pub  owns_directory :  bool , 
@@ -895,7 +895,7 @@ impl<'a> Parser<'a> {
895895                                         sep :  SeqSep , 
896896                                         f :  F ) 
897897                                         -> Vec < T > 
898-         where  F :  FnMut ( & mut  Parser < ' a > )  -> PResult < ' a ,   T > , 
898+         where  F :  FnMut ( & mut  Parser < ' a > )  -> PResult < ' a ,   T > 
899899    { 
900900        self . parse_seq_to_before_tokens ( & [ ket] ,  sep,  f,  |mut  e| e. emit ( ) ) 
901901    } 
@@ -2755,8 +2755,8 @@ impl<'a> Parser<'a> {
27552755                let  mut  err:  DiagnosticBuilder < ' a >  =
27562756                    self . diagnostic ( ) . struct_span_err ( self . span , 
27572757                                                      "this file contains an un-closed delimiter" ) ; 
2758-                 for  sp  in  & self . open_braces  { 
2759-                     err. span_help ( * sp,  "did you mean to close this delimiter?" ) ; 
2758+                 for  & ( _ ,  sp )  in  & self . open_braces  { 
2759+                     err. span_help ( sp,  "did you mean to close this delimiter?" ) ; 
27602760                } 
27612761
27622762                Err ( err) 
@@ -2766,23 +2766,66 @@ impl<'a> Parser<'a> {
27662766                let  pre_span = self . span ; 
27672767
27682768                // Parse the open delimiter. 
2769-                 self . open_braces . push ( self . span ) ; 
2769+                 self . open_braces . push ( ( delim ,   self . span ) ) ; 
27702770                let  open_span = self . span ; 
27712771                self . bump ( ) ; 
27722772
2773-                 // Parse the token trees within the delimiters 
2774-                 let  tts = self . parse_seq_to_before_end ( & token:: CloseDelim ( delim) , 
2775-                                                        SeqSep :: none ( ) , 
2776-                                                        |p| p. parse_token_tree ( ) ) ; 
2773+                 // Parse the token trees within the delimiters. 
2774+                 // We stop at any delimiter so we can try to recover if the user 
2775+                 // uses an incorrect delimiter. 
2776+                 let  tts = self . parse_seq_to_before_tokens ( & [ & token:: CloseDelim ( token:: Brace ) , 
2777+                                                             & token:: CloseDelim ( token:: Paren ) , 
2778+                                                             & token:: CloseDelim ( token:: Bracket ) ] , 
2779+                                                           SeqSep :: none ( ) , 
2780+                                                           |p| p. parse_token_tree ( ) , 
2781+                                                           |mut  e| e. emit ( ) ) ; 
27772782
2778-                 // Parse the close delimiter. 
27792783                let  close_span = self . span ; 
2780-                 self . bump ( ) ; 
2781-                 self . open_braces . pop ( ) . unwrap ( ) ; 
2782- 
27832784                // Expand to cover the entire delimited token tree 
27842785                let  span = Span  {  hi :  close_span. hi ,  ..pre_span } ; 
27852786
2787+                 match  self . token  { 
2788+                     // Correct delmiter. 
2789+                     token:: CloseDelim ( d)  if  d == delim => { 
2790+                         self . open_braces . pop ( ) . unwrap ( ) ; 
2791+ 
2792+                         // Parse the close delimiter. 
2793+                         self . bump ( ) ; 
2794+                     } 
2795+                     // Incorect delimiter. 
2796+                     token:: CloseDelim ( other)  => { 
2797+                         let  token_str = self . this_token_to_string ( ) ; 
2798+                         let  mut  err = self . diagnostic ( ) . struct_span_err ( self . span , 
2799+                             & format ! ( "incorrect close delimiter: `{}`" ,  token_str) ) ; 
2800+                         // This is a conservative error: only report the last unclosed delimiter. 
2801+                         // The previous unclosed delimiters could actually be closed! The parser 
2802+                         // just hasn't gotten to them yet. 
2803+                         if  let  Some ( & ( _,  sp) )  = self . open_braces . last ( )  { 
2804+                             err. span_note ( sp,  "unclosed delimiter" ) ; 
2805+                         } ; 
2806+                         err. emit ( ) ; 
2807+ 
2808+                         self . open_braces . pop ( ) . unwrap ( ) ; 
2809+ 
2810+                         // If the incorrect delimter matches an earlier opening 
2811+                         // delimiter, then don't consume it (it can be used to 
2812+                         // close the earlier one)Otherwise, consume it. 
2813+                         // E.g., we try to recover from: 
2814+                         // fn foo() { 
2815+                         //     bar(baz( 
2816+                         // }  // Incorrect delimiter but matches the earlier `{` 
2817+                         if  !self . open_braces . iter ( ) . any ( |& ( b,  _) | b == other)  { 
2818+                             self . bump ( ) ; 
2819+                         } 
2820+                     } 
2821+                     token:: Eof  => { 
2822+                         // Silently recover, the EOF token will be seen again 
2823+                         // and an error emitted then. Thus we don't pop from 
2824+                         // self.open_braces here. 
2825+                     } , 
2826+                     _ => unreachable ! ( ) , 
2827+                 } 
2828+ 
27862829                Ok ( TokenTree :: Delimited ( span,  Rc :: new ( Delimited  { 
27872830                    delim :  delim, 
27882831                    open_span :  open_span, 
@@ -2798,16 +2841,11 @@ impl<'a> Parser<'a> {
27982841                maybe_whole ! ( deref self ,  NtTT ) ; 
27992842                match  self . token  { 
28002843                    token:: CloseDelim ( _)  => { 
2844+                         // An unexpected closing delimiter (i.e., there is no 
2845+                         // matching opening delimiter). 
28012846                        let  token_str = self . this_token_to_string ( ) ; 
2802-                         let  mut  err = self . diagnostic ( ) . struct_span_err ( self . span , 
2803-                             & format ! ( "incorrect close delimiter: `{}`" ,  token_str) ) ; 
2804-                         // This is a conservative error: only report the last unclosed delimiter. 
2805-                         // The previous unclosed delimiters could actually be closed! The parser 
2806-                         // just hasn't gotten to them yet. 
2807-                         if  let  Some ( & sp)  = self . open_braces . last ( )  { 
2808-                             err. span_note ( sp,  "unclosed delimiter" ) ; 
2809-                         } ; 
2810- 
2847+                         let  err = self . diagnostic ( ) . struct_span_err ( self . span , 
2848+                             & format ! ( "unexpected close delimiter: `{}`" ,  token_str) ) ; 
28112849                        Err ( err) 
28122850                    } , 
28132851                    /* we ought to allow different depths of unquotation */ 
@@ -3825,7 +3863,9 @@ impl<'a> Parser<'a> {
38253863    fn  recover_stmt_ ( & mut  self ,  break_on_semi :  SemiColonMode )  { 
38263864        let  mut  brace_depth = 0 ; 
38273865        let  mut  bracket_depth = 0 ; 
3866+         debug ! ( "recover_stmt_ enter loop" ) ; 
38283867        loop  { 
3868+             debug ! ( "recover_stmt_ loop {:?}" ,  self . token) ; 
38293869            match  self . token  { 
38303870                token:: OpenDelim ( token:: DelimToken :: Brace )  => { 
38313871                    brace_depth += 1 ; 
@@ -3837,6 +3877,7 @@ impl<'a> Parser<'a> {
38373877                } 
38383878                token:: CloseDelim ( token:: DelimToken :: Brace )  => { 
38393879                    if  brace_depth == 0  { 
3880+                         debug ! ( "recover_stmt_ return - close delim {:?}" ,  self . token) ; 
38403881                        return ; 
38413882                    } 
38423883                    brace_depth -= 1 ; 
@@ -3849,12 +3890,16 @@ impl<'a> Parser<'a> {
38493890                    } 
38503891                    self . bump ( ) ; 
38513892                } 
3852-                 token:: Eof  => return , 
3893+                 token:: Eof  => { 
3894+                     debug ! ( "recover_stmt_ return - Eof" ) ; 
3895+                     return ; 
3896+                 } 
38533897                token:: Semi  => { 
38543898                    self . bump ( ) ; 
38553899                    if  break_on_semi == SemiColonMode :: Break  &&
38563900                       brace_depth == 0  &&
38573901                       bracket_depth == 0  { 
3902+                         debug ! ( "recover_stmt_ return - Semi" ) ; 
38583903                        return ; 
38593904                    } 
38603905                } 
@@ -4043,6 +4088,8 @@ impl<'a> Parser<'a> {
40434088        while  !self . eat ( & token:: CloseDelim ( token:: Brace ) )  { 
40444089            let  Spanned  { node,  span}  = if  let  Some ( s)  = self . parse_stmt_ ( )  { 
40454090                s
4091+             }  else  if  self . token  == token:: Eof  { 
4092+                 break ; 
40464093            }  else  { 
40474094                // Found only `;` or `}`. 
40484095                continue ; 
0 commit comments