@@ -268,8 +268,8 @@ pub struct Parser<'a> {
268268 /// Used to determine the path to externally loaded source files
269269 pub 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.
275275 pub 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