@@ -250,6 +250,8 @@ pub struct Parser<'a> {
250
250
desugar_doc_comments : bool ,
251
251
/// Whether we should configure out of line modules as we parse.
252
252
pub cfg_mods : bool ,
253
+ /// Unmatched open delimiters, used for parse recovery when multiple tokens could be valid.
254
+ crate open_braces : Vec < ( token:: DelimToken , Span ) > ,
253
255
}
254
256
255
257
@@ -569,6 +571,7 @@ impl<'a> Parser<'a> {
569
571
} ,
570
572
desugar_doc_comments,
571
573
cfg_mods : true ,
574
+ open_braces : Vec :: new ( ) ,
572
575
} ;
573
576
574
577
let tok = parser. next_tok ( ) ;
@@ -635,6 +638,55 @@ impl<'a> Parser<'a> {
635
638
}
636
639
}
637
640
641
+ fn recover_closing_delimiter (
642
+ & mut self ,
643
+ tokens : & [ token:: Token ] ,
644
+ mut err : DiagnosticBuilder < ' a > ,
645
+ ) -> PResult < ' a , ( ) > {
646
+ let mut pos = None ;
647
+ let mut tokens: Vec < token:: Token > = tokens. iter ( ) . map ( |t| ( * t) . clone ( ) ) . collect ( ) ;
648
+ tokens. extend ( self . expected_tokens . iter ( ) . filter_map ( |t| match t {
649
+ TokenType :: Token ( t) => Some ( ( * t) . clone ( ) ) ,
650
+ _ => None ,
651
+ } ) ) ;
652
+ for ( i, ( delim, span) ) in self . open_braces . iter ( ) . enumerate ( ) {
653
+ if tokens. contains ( & token:: CloseDelim ( * delim) ) && self . span > * span {
654
+ pos = Some ( i) ;
655
+ // do not break, we want to use the last one that would apply
656
+ }
657
+ }
658
+ match pos {
659
+ Some ( pos) => {
660
+ // Recover and assume that the detected unclosed delimiter was meant for
661
+ // this location. Emit the diagnostic and act as if the delimiter was
662
+ // present for the parser's sake.
663
+
664
+ // Don't attempt to recover from this unclosed delimiter more than once.
665
+ let ( delim, open_sp) = self . open_braces . remove ( pos) ;
666
+ let delim = TokenType :: Token ( token:: CloseDelim ( delim) ) ;
667
+
668
+ // We want to suggest the inclusion of the closing delimiter where it makes
669
+ // the most sense, which is immediately after the last token:
670
+ //
671
+ // {foo(bar {}}
672
+ // - - ^ expected one of `)`, <...>
673
+ // | |
674
+ // | help: ...missing `)` might belong here
675
+ // you might have meant to close this...
676
+ err. span_label ( open_sp, "if you meant to close this..." ) ;
677
+ err. span_suggestion_short_with_applicability (
678
+ self . sess . source_map ( ) . next_point ( self . prev_span ) ,
679
+ & format ! ( "...the missing {} may belong here" , delim. to_string( ) ) ,
680
+ delim. to_string ( ) ,
681
+ Applicability :: MaybeIncorrect ,
682
+ ) ;
683
+ err. emit ( ) ;
684
+ Ok ( ( ) )
685
+ }
686
+ _ => Err ( err) ,
687
+ }
688
+ }
689
+
638
690
/// Expect and consume the token t. Signal an error if
639
691
/// the next token is not t.
640
692
pub fn expect ( & mut self , t : & token:: Token ) -> PResult < ' a , ( ) > {
@@ -668,7 +720,7 @@ impl<'a> Parser<'a> {
668
720
err. span_label ( self . span , "unexpected token" ) ;
669
721
}
670
722
}
671
- Err ( err)
723
+ self . recover_closing_delimiter ( & [ t . clone ( ) ] , err)
672
724
}
673
725
} else {
674
726
self . expect_one_of ( slice:: from_ref ( t) , & [ ] )
@@ -761,7 +813,7 @@ impl<'a> Parser<'a> {
761
813
err. span_label ( self . span , "unexpected token" ) ;
762
814
}
763
815
}
764
- Err ( err)
816
+ self . recover_closing_delimiter ( edible , err)
765
817
}
766
818
}
767
819
@@ -1075,11 +1127,12 @@ impl<'a> Parser<'a> {
1075
1127
/// Parse a sequence, not including the closing delimiter. The function
1076
1128
/// f must consume tokens until reaching the next separator or
1077
1129
/// closing bracket.
1078
- pub fn parse_seq_to_before_end < T , F > ( & mut self ,
1079
- ket : & token:: Token ,
1080
- sep : SeqSep ,
1081
- f : F )
1082
- -> PResult < ' a , Vec < T > >
1130
+ pub fn parse_seq_to_before_end < T , F > (
1131
+ & mut self ,
1132
+ ket : & token:: Token ,
1133
+ sep : SeqSep ,
1134
+ f : F ,
1135
+ ) -> PResult < ' a , Vec < T > >
1083
1136
where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T >
1084
1137
{
1085
1138
self . parse_seq_to_before_tokens ( & [ ket] , sep, TokenExpectType :: Expect , f)
@@ -1124,8 +1177,12 @@ impl<'a> Parser<'a> {
1124
1177
v. push ( t) ;
1125
1178
continue ;
1126
1179
} ,
1127
- Err ( mut e) => {
1128
- e. cancel ( ) ;
1180
+ Err ( mut err) => {
1181
+ err. cancel ( ) ;
1182
+ let kets: Vec < token:: Token > = kets. iter ( )
1183
+ . map ( |t| ( * t) . clone ( ) )
1184
+ . collect ( ) ;
1185
+ let _ = self . recover_closing_delimiter ( & kets[ ..] , e) ;
1129
1186
break ;
1130
1187
}
1131
1188
}
@@ -1141,7 +1198,13 @@ impl<'a> Parser<'a> {
1141
1198
break ;
1142
1199
}
1143
1200
1144
- let t = f ( self ) ?;
1201
+ let t = match f ( self ) {
1202
+ Ok ( t) => t,
1203
+ Err ( e) => {
1204
+ let kets: Vec < token:: Token > = kets. iter ( ) . map ( |t| ( * t) . clone ( ) ) . collect ( ) ;
1205
+ return self . recover_closing_delimiter ( & kets[ ..] , e) . map ( |_| v) ;
1206
+ }
1207
+ } ;
1145
1208
v. push ( t) ;
1146
1209
}
1147
1210
@@ -1151,12 +1214,13 @@ impl<'a> Parser<'a> {
1151
1214
/// Parse a sequence, including the closing delimiter. The function
1152
1215
/// f must consume tokens until reaching the next separator or
1153
1216
/// closing bracket.
1154
- fn parse_unspanned_seq < T , F > ( & mut self ,
1155
- bra : & token:: Token ,
1156
- ket : & token:: Token ,
1157
- sep : SeqSep ,
1158
- f : F )
1159
- -> PResult < ' a , Vec < T > > where
1217
+ fn parse_unspanned_seq < T , F > (
1218
+ & mut self ,
1219
+ bra : & token:: Token ,
1220
+ ket : & token:: Token ,
1221
+ sep : SeqSep ,
1222
+ f : F ,
1223
+ ) -> PResult < ' a , Vec < T > > where
1160
1224
F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
1161
1225
{
1162
1226
self . expect ( bra) ?;
0 commit comments