@@ -5,6 +5,7 @@ use super::{
55 SemiColonMode , SeqSep , TokenExpectType , TokenType ,
66} ;
77
8+ use crate :: lexer:: UnmatchedBrace ;
89use rustc_ast as ast;
910use rustc_ast:: ptr:: P ;
1011use rustc_ast:: token:: { self , Lit , LitKind , TokenKind } ;
@@ -21,6 +22,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult};
2122use rustc_span:: source_map:: Spanned ;
2223use rustc_span:: symbol:: { kw, Ident } ;
2324use rustc_span:: { MultiSpan , Span , SpanSnippetError , DUMMY_SP } ;
25+ use std:: ops:: { Deref , DerefMut } ;
2426
2527use std:: mem:: take;
2628
@@ -154,6 +156,28 @@ impl AttemptLocalParseRecovery {
154156 }
155157}
156158
159+ // SnapshotParser is used to create a snapshot of the parser
160+ // without causing duplicate errors being emitted when the `Parser`
161+ // is dropped.
162+ pub ( super ) struct SnapshotParser < ' a > {
163+ parser : Parser < ' a > ,
164+ unclosed_delims : Vec < UnmatchedBrace > ,
165+ }
166+
167+ impl < ' a > Deref for SnapshotParser < ' a > {
168+ type Target = Parser < ' a > ;
169+
170+ fn deref ( & self ) -> & Self :: Target {
171+ & self . parser
172+ }
173+ }
174+
175+ impl < ' a > DerefMut for SnapshotParser < ' a > {
176+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
177+ & mut self . parser
178+ }
179+ }
180+
157181impl < ' a > Parser < ' a > {
158182 pub ( super ) fn span_err < S : Into < MultiSpan > > (
159183 & self ,
@@ -179,6 +203,25 @@ impl<'a> Parser<'a> {
179203 & self . sess . span_diagnostic
180204 }
181205
206+ /// Relace `self` with `snapshot.parser` and extend `unclosed_delims` with `snapshot.unclosed_delims`.
207+ /// This is to avoid losing unclosed delims errors `create_snapshot_for_diagnostic` clears.
208+ pub ( super ) fn restore_snapshot ( & mut self , snapshot : SnapshotParser < ' a > ) {
209+ * self = snapshot. parser ;
210+ self . unclosed_delims . extend ( snapshot. unclosed_delims . clone ( ) ) ;
211+ }
212+
213+ /// Create a snapshot of the `Parser`.
214+ pub ( super ) fn create_snapshot_for_diagnostic ( & self ) -> SnapshotParser < ' a > {
215+ let mut snapshot = self . clone ( ) ;
216+ let unclosed_delims = self . unclosed_delims . clone ( ) ;
217+ // Clear `unclosed_delims` in snapshot to avoid
218+ // duplicate errors being emitted when the `Parser`
219+ // is dropped (which may or may not happen, depending
220+ // if the parsing the snapshot is created for is successful)
221+ snapshot. unclosed_delims . clear ( ) ;
222+ SnapshotParser { parser : snapshot, unclosed_delims }
223+ }
224+
182225 pub ( super ) fn span_to_snippet ( & self , span : Span ) -> Result < String , SpanSnippetError > {
183226 self . sess . source_map ( ) . span_to_snippet ( span)
184227 }
@@ -438,7 +481,7 @@ impl<'a> Parser<'a> {
438481 // fn foo() -> Foo {
439482 // field: value,
440483 // }
441- let mut snapshot = self . clone ( ) ;
484+ let mut snapshot = self . create_snapshot_for_diagnostic ( ) ;
442485 let path =
443486 Path { segments : vec ! [ ] , span : self . prev_token . span . shrink_to_lo ( ) , tokens : None } ;
444487 let struct_expr = snapshot. parse_struct_expr ( None , path, AttrVec :: new ( ) , false ) ;
@@ -464,7 +507,7 @@ impl<'a> Parser<'a> {
464507 Applicability :: MaybeIncorrect ,
465508 )
466509 . emit ( ) ;
467- * self = snapshot;
510+ self . restore_snapshot ( snapshot) ;
468511 let mut tail = self . mk_block (
469512 vec ! [ self . mk_stmt_err( expr. span) ] ,
470513 s,
@@ -678,7 +721,7 @@ impl<'a> Parser<'a> {
678721 /// angle brackets.
679722 pub ( super ) fn check_turbofish_missing_angle_brackets ( & mut self , segment : & mut PathSegment ) {
680723 if token:: ModSep == self . token . kind && segment. args . is_none ( ) {
681- let snapshot = self . clone ( ) ;
724+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
682725 self . bump ( ) ;
683726 let lo = self . token . span ;
684727 match self . parse_angle_args ( None ) {
@@ -712,14 +755,14 @@ impl<'a> Parser<'a> {
712755 . emit ( ) ;
713756 } else {
714757 // This doesn't look like an invalid turbofish, can't recover parse state.
715- * self = snapshot;
758+ self . restore_snapshot ( snapshot) ;
716759 }
717760 }
718761 Err ( err) => {
719762 // We couldn't parse generic parameters, unlikely to be a turbofish. Rely on
720763 // generic parse error instead.
721764 err. cancel ( ) ;
722- * self = snapshot;
765+ self . restore_snapshot ( snapshot) ;
723766 }
724767 }
725768 }
@@ -825,7 +868,7 @@ impl<'a> Parser<'a> {
825868 // `x == y < z`
826869 ( BinOpKind :: Eq , AssocOp :: Less | AssocOp :: LessEqual | AssocOp :: Greater | AssocOp :: GreaterEqual ) => {
827870 // Consume `z`/outer-op-rhs.
828- let snapshot = self . clone ( ) ;
871+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
829872 match self . parse_expr ( ) {
830873 Ok ( r2) => {
831874 // We are sure that outer-op-rhs could be consumed, the suggestion is
@@ -835,14 +878,14 @@ impl<'a> Parser<'a> {
835878 }
836879 Err ( expr_err) => {
837880 expr_err. cancel ( ) ;
838- * self = snapshot;
881+ self . restore_snapshot ( snapshot) ;
839882 false
840883 }
841884 }
842885 }
843886 // `x > y == z`
844887 ( BinOpKind :: Lt | BinOpKind :: Le | BinOpKind :: Gt | BinOpKind :: Ge , AssocOp :: Equal ) => {
845- let snapshot = self . clone ( ) ;
888+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
846889 // At this point it is always valid to enclose the lhs in parentheses, no
847890 // further checks are necessary.
848891 match self . parse_expr ( ) {
@@ -852,7 +895,7 @@ impl<'a> Parser<'a> {
852895 }
853896 Err ( expr_err) => {
854897 expr_err. cancel ( ) ;
855- * self = snapshot;
898+ self . restore_snapshot ( snapshot) ;
856899 false
857900 }
858901 }
@@ -917,7 +960,7 @@ impl<'a> Parser<'a> {
917960 || outer_op. node == AssocOp :: Greater
918961 {
919962 if outer_op. node == AssocOp :: Less {
920- let snapshot = self . clone ( ) ;
963+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
921964 self . bump ( ) ;
922965 // So far we have parsed `foo<bar<`, consume the rest of the type args.
923966 let modifiers =
@@ -929,15 +972,15 @@ impl<'a> Parser<'a> {
929972 {
930973 // We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the
931974 // parser and bail out.
932- * self = snapshot . clone ( ) ;
975+ self . restore_snapshot ( snapshot ) ;
933976 }
934977 }
935978 return if token:: ModSep == self . token . kind {
936979 // We have some certainty that this was a bad turbofish at this point.
937980 // `foo< bar >::`
938981 suggest ( & mut err) ;
939982
940- let snapshot = self . clone ( ) ;
983+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
941984 self . bump ( ) ; // `::`
942985
943986 // Consume the rest of the likely `foo<bar>::new()` or return at `foo<bar>`.
@@ -954,7 +997,7 @@ impl<'a> Parser<'a> {
954997 expr_err. cancel ( ) ;
955998 // Not entirely sure now, but we bubble the error up with the
956999 // suggestion.
957- * self = snapshot;
1000+ self . restore_snapshot ( snapshot) ;
9581001 Err ( err)
9591002 }
9601003 }
@@ -1008,7 +1051,7 @@ impl<'a> Parser<'a> {
10081051 }
10091052
10101053 fn consume_fn_args ( & mut self ) -> Result < ( ) , ( ) > {
1011- let snapshot = self . clone ( ) ;
1054+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
10121055 self . bump ( ) ; // `(`
10131056
10141057 // Consume the fn call arguments.
@@ -1018,7 +1061,7 @@ impl<'a> Parser<'a> {
10181061
10191062 if self . token . kind == token:: Eof {
10201063 // Not entirely sure that what we consumed were fn arguments, rollback.
1021- * self = snapshot;
1064+ self . restore_snapshot ( snapshot) ;
10221065 Err ( ( ) )
10231066 } else {
10241067 // 99% certain that the suggestion is correct, continue parsing.
@@ -1959,12 +2002,12 @@ impl<'a> Parser<'a> {
19592002 }
19602003
19612004 fn recover_const_param_decl ( & mut self , ty_generics : Option < & Generics > ) -> Option < GenericArg > {
1962- let snapshot = self . clone ( ) ;
2005+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
19632006 let param = match self . parse_const_param ( vec ! [ ] ) {
19642007 Ok ( param) => param,
19652008 Err ( err) => {
19662009 err. cancel ( ) ;
1967- * self = snapshot;
2010+ self . restore_snapshot ( snapshot) ;
19682011 return None ;
19692012 }
19702013 } ;
@@ -2056,7 +2099,7 @@ impl<'a> Parser<'a> {
20562099 // We perform these checks and early return to avoid taking a snapshot unnecessarily.
20572100 return Err ( err) ;
20582101 }
2059- let snapshot = self . clone ( ) ;
2102+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
20602103 if is_op_or_dot {
20612104 self . bump ( ) ;
20622105 }
@@ -2101,7 +2144,7 @@ impl<'a> Parser<'a> {
21012144 err. cancel ( ) ;
21022145 }
21032146 }
2104- * self = snapshot;
2147+ self . restore_snapshot ( snapshot) ;
21052148 Err ( err)
21062149 }
21072150
@@ -2161,7 +2204,7 @@ impl<'a> Parser<'a> {
21612204 let span = self . token . span ;
21622205 // We only emit "unexpected `:`" error here if we can successfully parse the
21632206 // whole pattern correctly in that case.
2164- let snapshot = self . clone ( ) ;
2207+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
21652208
21662209 // Create error for "unexpected `:`".
21672210 match self . expected_one_of_not_found ( & [ ] , & [ ] ) {
@@ -2173,7 +2216,7 @@ impl<'a> Parser<'a> {
21732216 // reasonable error.
21742217 inner_err. cancel ( ) ;
21752218 err. cancel ( ) ;
2176- * self = snapshot;
2219+ self . restore_snapshot ( snapshot) ;
21772220 }
21782221 Ok ( mut pat) => {
21792222 // We've parsed the rest of the pattern.
@@ -2252,7 +2295,7 @@ impl<'a> Parser<'a> {
22522295 }
22532296 _ => {
22542297 // Carry on as if we had not done anything. This should be unreachable.
2255- * self = snapshot;
2298+ self . restore_snapshot ( snapshot) ;
22562299 }
22572300 } ;
22582301 first_pat
0 commit comments