@@ -268,8 +268,8 @@ pub struct Parser<'a> {
268
268
/// Used to determine the path to externally loaded source files
269
269
pub filename : Option < String > ,
270
270
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 ) > ,
273
273
/// Flag if this parser "owns" the directory that it is currently parsing
274
274
/// in. This will affect how nested files are looked up.
275
275
pub owns_directory : bool ,
@@ -895,7 +895,7 @@ impl<'a> Parser<'a> {
895
895
sep : SeqSep ,
896
896
f : F )
897
897
-> Vec < T >
898
- where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
898
+ where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T >
899
899
{
900
900
self . parse_seq_to_before_tokens ( & [ ket] , sep, f, |mut e| e. emit ( ) )
901
901
}
@@ -2755,8 +2755,8 @@ impl<'a> Parser<'a> {
2755
2755
let mut err: DiagnosticBuilder < ' a > =
2756
2756
self . diagnostic ( ) . struct_span_err ( self . span ,
2757
2757
"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?" ) ;
2760
2760
}
2761
2761
2762
2762
Err ( err)
@@ -2766,23 +2766,66 @@ impl<'a> Parser<'a> {
2766
2766
let pre_span = self . span ;
2767
2767
2768
2768
// Parse the open delimiter.
2769
- self . open_braces . push ( self . span ) ;
2769
+ self . open_braces . push ( ( delim , self . span ) ) ;
2770
2770
let open_span = self . span ;
2771
2771
self . bump ( ) ;
2772
2772
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 ( ) ) ;
2777
2782
2778
- // Parse the close delimiter.
2779
2783
let close_span = self . span ;
2780
- self . bump ( ) ;
2781
- self . open_braces . pop ( ) . unwrap ( ) ;
2782
-
2783
2784
// Expand to cover the entire delimited token tree
2784
2785
let span = Span { hi : close_span. hi , ..pre_span } ;
2785
2786
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
+
2786
2829
Ok ( TokenTree :: Delimited ( span, Rc :: new ( Delimited {
2787
2830
delim : delim,
2788
2831
open_span : open_span,
@@ -2798,16 +2841,11 @@ impl<'a> Parser<'a> {
2798
2841
maybe_whole ! ( deref self , NtTT ) ;
2799
2842
match self . token {
2800
2843
token:: CloseDelim ( _) => {
2844
+ // An unexpected closing delimiter (i.e., there is no
2845
+ // matching opening delimiter).
2801
2846
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) ) ;
2811
2849
Err ( err)
2812
2850
} ,
2813
2851
/* we ought to allow different depths of unquotation */
@@ -3825,7 +3863,9 @@ impl<'a> Parser<'a> {
3825
3863
fn recover_stmt_ ( & mut self , break_on_semi : SemiColonMode ) {
3826
3864
let mut brace_depth = 0 ;
3827
3865
let mut bracket_depth = 0 ;
3866
+ debug ! ( "recover_stmt_ enter loop" ) ;
3828
3867
loop {
3868
+ debug ! ( "recover_stmt_ loop {:?}" , self . token) ;
3829
3869
match self . token {
3830
3870
token:: OpenDelim ( token:: DelimToken :: Brace ) => {
3831
3871
brace_depth += 1 ;
@@ -3837,6 +3877,7 @@ impl<'a> Parser<'a> {
3837
3877
}
3838
3878
token:: CloseDelim ( token:: DelimToken :: Brace ) => {
3839
3879
if brace_depth == 0 {
3880
+ debug ! ( "recover_stmt_ return - close delim {:?}" , self . token) ;
3840
3881
return ;
3841
3882
}
3842
3883
brace_depth -= 1 ;
@@ -3849,12 +3890,16 @@ impl<'a> Parser<'a> {
3849
3890
}
3850
3891
self . bump ( ) ;
3851
3892
}
3852
- token:: Eof => return ,
3893
+ token:: Eof => {
3894
+ debug ! ( "recover_stmt_ return - Eof" ) ;
3895
+ return ;
3896
+ }
3853
3897
token:: Semi => {
3854
3898
self . bump ( ) ;
3855
3899
if break_on_semi == SemiColonMode :: Break &&
3856
3900
brace_depth == 0 &&
3857
3901
bracket_depth == 0 {
3902
+ debug ! ( "recover_stmt_ return - Semi" ) ;
3858
3903
return ;
3859
3904
}
3860
3905
}
@@ -4043,6 +4088,8 @@ impl<'a> Parser<'a> {
4043
4088
while !self . eat ( & token:: CloseDelim ( token:: Brace ) ) {
4044
4089
let Spanned { node, span} = if let Some ( s) = self . parse_stmt_ ( ) {
4045
4090
s
4091
+ } else if self . token == token:: Eof {
4092
+ break ;
4046
4093
} else {
4047
4094
// Found only `;` or `}`.
4048
4095
continue ;
0 commit comments