@@ -5,6 +5,7 @@ use super::{
5
5
SemiColonMode , SeqSep , TokenExpectType , TokenType ,
6
6
} ;
7
7
8
+ use crate :: lexer:: UnmatchedBrace ;
8
9
use rustc_ast as ast;
9
10
use rustc_ast:: ptr:: P ;
10
11
use rustc_ast:: token:: { self , Lit , LitKind , TokenKind } ;
@@ -21,6 +22,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult};
21
22
use rustc_span:: source_map:: Spanned ;
22
23
use rustc_span:: symbol:: { kw, Ident } ;
23
24
use rustc_span:: { MultiSpan , Span , SpanSnippetError , DUMMY_SP } ;
25
+ use std:: ops:: { Deref , DerefMut } ;
24
26
25
27
use std:: mem:: take;
26
28
@@ -154,6 +156,28 @@ impl AttemptLocalParseRecovery {
154
156
}
155
157
}
156
158
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
+
157
181
impl < ' a > Parser < ' a > {
158
182
pub ( super ) fn span_err < S : Into < MultiSpan > > (
159
183
& self ,
@@ -179,6 +203,25 @@ impl<'a> Parser<'a> {
179
203
& self . sess . span_diagnostic
180
204
}
181
205
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
+
182
225
pub ( super ) fn span_to_snippet ( & self , span : Span ) -> Result < String , SpanSnippetError > {
183
226
self . sess . source_map ( ) . span_to_snippet ( span)
184
227
}
@@ -438,7 +481,7 @@ impl<'a> Parser<'a> {
438
481
// fn foo() -> Foo {
439
482
// field: value,
440
483
// }
441
- let mut snapshot = self . clone ( ) ;
484
+ let mut snapshot = self . create_snapshot_for_diagnostic ( ) ;
442
485
let path =
443
486
Path { segments : vec ! [ ] , span : self . prev_token . span . shrink_to_lo ( ) , tokens : None } ;
444
487
let struct_expr = snapshot. parse_struct_expr ( None , path, AttrVec :: new ( ) , false ) ;
@@ -464,7 +507,7 @@ impl<'a> Parser<'a> {
464
507
Applicability :: MaybeIncorrect ,
465
508
)
466
509
. emit ( ) ;
467
- * self = snapshot;
510
+ self . restore_snapshot ( snapshot) ;
468
511
let mut tail = self . mk_block (
469
512
vec ! [ self . mk_stmt_err( expr. span) ] ,
470
513
s,
@@ -678,7 +721,7 @@ impl<'a> Parser<'a> {
678
721
/// angle brackets.
679
722
pub ( super ) fn check_turbofish_missing_angle_brackets ( & mut self , segment : & mut PathSegment ) {
680
723
if token:: ModSep == self . token . kind && segment. args . is_none ( ) {
681
- let snapshot = self . clone ( ) ;
724
+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
682
725
self . bump ( ) ;
683
726
let lo = self . token . span ;
684
727
match self . parse_angle_args ( None ) {
@@ -712,14 +755,14 @@ impl<'a> Parser<'a> {
712
755
. emit ( ) ;
713
756
} else {
714
757
// This doesn't look like an invalid turbofish, can't recover parse state.
715
- * self = snapshot;
758
+ self . restore_snapshot ( snapshot) ;
716
759
}
717
760
}
718
761
Err ( err) => {
719
762
// We couldn't parse generic parameters, unlikely to be a turbofish. Rely on
720
763
// generic parse error instead.
721
764
err. cancel ( ) ;
722
- * self = snapshot;
765
+ self . restore_snapshot ( snapshot) ;
723
766
}
724
767
}
725
768
}
@@ -825,7 +868,7 @@ impl<'a> Parser<'a> {
825
868
// `x == y < z`
826
869
( BinOpKind :: Eq , AssocOp :: Less | AssocOp :: LessEqual | AssocOp :: Greater | AssocOp :: GreaterEqual ) => {
827
870
// Consume `z`/outer-op-rhs.
828
- let snapshot = self . clone ( ) ;
871
+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
829
872
match self . parse_expr ( ) {
830
873
Ok ( r2) => {
831
874
// We are sure that outer-op-rhs could be consumed, the suggestion is
@@ -835,14 +878,14 @@ impl<'a> Parser<'a> {
835
878
}
836
879
Err ( expr_err) => {
837
880
expr_err. cancel ( ) ;
838
- * self = snapshot;
881
+ self . restore_snapshot ( snapshot) ;
839
882
false
840
883
}
841
884
}
842
885
}
843
886
// `x > y == z`
844
887
( BinOpKind :: Lt | BinOpKind :: Le | BinOpKind :: Gt | BinOpKind :: Ge , AssocOp :: Equal ) => {
845
- let snapshot = self . clone ( ) ;
888
+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
846
889
// At this point it is always valid to enclose the lhs in parentheses, no
847
890
// further checks are necessary.
848
891
match self . parse_expr ( ) {
@@ -852,7 +895,7 @@ impl<'a> Parser<'a> {
852
895
}
853
896
Err ( expr_err) => {
854
897
expr_err. cancel ( ) ;
855
- * self = snapshot;
898
+ self . restore_snapshot ( snapshot) ;
856
899
false
857
900
}
858
901
}
@@ -917,7 +960,7 @@ impl<'a> Parser<'a> {
917
960
|| outer_op. node == AssocOp :: Greater
918
961
{
919
962
if outer_op. node == AssocOp :: Less {
920
- let snapshot = self . clone ( ) ;
963
+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
921
964
self . bump ( ) ;
922
965
// So far we have parsed `foo<bar<`, consume the rest of the type args.
923
966
let modifiers =
@@ -929,15 +972,15 @@ impl<'a> Parser<'a> {
929
972
{
930
973
// We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the
931
974
// parser and bail out.
932
- * self = snapshot . clone ( ) ;
975
+ self . restore_snapshot ( snapshot ) ;
933
976
}
934
977
}
935
978
return if token:: ModSep == self . token . kind {
936
979
// We have some certainty that this was a bad turbofish at this point.
937
980
// `foo< bar >::`
938
981
suggest ( & mut err) ;
939
982
940
- let snapshot = self . clone ( ) ;
983
+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
941
984
self . bump ( ) ; // `::`
942
985
943
986
// Consume the rest of the likely `foo<bar>::new()` or return at `foo<bar>`.
@@ -954,7 +997,7 @@ impl<'a> Parser<'a> {
954
997
expr_err. cancel ( ) ;
955
998
// Not entirely sure now, but we bubble the error up with the
956
999
// suggestion.
957
- * self = snapshot;
1000
+ self . restore_snapshot ( snapshot) ;
958
1001
Err ( err)
959
1002
}
960
1003
}
@@ -1008,7 +1051,7 @@ impl<'a> Parser<'a> {
1008
1051
}
1009
1052
1010
1053
fn consume_fn_args ( & mut self ) -> Result < ( ) , ( ) > {
1011
- let snapshot = self . clone ( ) ;
1054
+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
1012
1055
self . bump ( ) ; // `(`
1013
1056
1014
1057
// Consume the fn call arguments.
@@ -1018,7 +1061,7 @@ impl<'a> Parser<'a> {
1018
1061
1019
1062
if self . token . kind == token:: Eof {
1020
1063
// Not entirely sure that what we consumed were fn arguments, rollback.
1021
- * self = snapshot;
1064
+ self . restore_snapshot ( snapshot) ;
1022
1065
Err ( ( ) )
1023
1066
} else {
1024
1067
// 99% certain that the suggestion is correct, continue parsing.
@@ -1959,12 +2002,12 @@ impl<'a> Parser<'a> {
1959
2002
}
1960
2003
1961
2004
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 ( ) ;
1963
2006
let param = match self . parse_const_param ( vec ! [ ] ) {
1964
2007
Ok ( param) => param,
1965
2008
Err ( err) => {
1966
2009
err. cancel ( ) ;
1967
- * self = snapshot;
2010
+ self . restore_snapshot ( snapshot) ;
1968
2011
return None ;
1969
2012
}
1970
2013
} ;
@@ -2056,7 +2099,7 @@ impl<'a> Parser<'a> {
2056
2099
// We perform these checks and early return to avoid taking a snapshot unnecessarily.
2057
2100
return Err ( err) ;
2058
2101
}
2059
- let snapshot = self . clone ( ) ;
2102
+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
2060
2103
if is_op_or_dot {
2061
2104
self . bump ( ) ;
2062
2105
}
@@ -2101,7 +2144,7 @@ impl<'a> Parser<'a> {
2101
2144
err. cancel ( ) ;
2102
2145
}
2103
2146
}
2104
- * self = snapshot;
2147
+ self . restore_snapshot ( snapshot) ;
2105
2148
Err ( err)
2106
2149
}
2107
2150
@@ -2161,7 +2204,7 @@ impl<'a> Parser<'a> {
2161
2204
let span = self . token . span ;
2162
2205
// We only emit "unexpected `:`" error here if we can successfully parse the
2163
2206
// whole pattern correctly in that case.
2164
- let snapshot = self . clone ( ) ;
2207
+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
2165
2208
2166
2209
// Create error for "unexpected `:`".
2167
2210
match self . expected_one_of_not_found ( & [ ] , & [ ] ) {
@@ -2173,7 +2216,7 @@ impl<'a> Parser<'a> {
2173
2216
// reasonable error.
2174
2217
inner_err. cancel ( ) ;
2175
2218
err. cancel ( ) ;
2176
- * self = snapshot;
2219
+ self . restore_snapshot ( snapshot) ;
2177
2220
}
2178
2221
Ok ( mut pat) => {
2179
2222
// We've parsed the rest of the pattern.
@@ -2252,7 +2295,7 @@ impl<'a> Parser<'a> {
2252
2295
}
2253
2296
_ => {
2254
2297
// Carry on as if we had not done anything. This should be unreachable.
2255
- * self = snapshot;
2298
+ self . restore_snapshot ( snapshot) ;
2256
2299
}
2257
2300
} ;
2258
2301
first_pat
0 commit comments