1
- use super :: pat:: { RecoverColon , RecoverComma , PARAM_EXPECTED } ;
1
+ use super :: pat:: { CommaRecoveryMode , RecoverColon , RecoverComma , PARAM_EXPECTED } ;
2
2
use super :: ty:: { AllowPlus , RecoverQPath , RecoverReturnSign } ;
3
3
use super :: {
4
4
AttrWrapper , BlockMode , ClosureSpans , ForceCollect , Parser , PathStyle , Restrictions , TokenType ,
@@ -1286,18 +1286,27 @@ impl<'a> Parser<'a> {
1286
1286
} else if let Some ( label) = self . eat_label ( ) {
1287
1287
self . parse_labeled_expr ( label, attrs, true )
1288
1288
} else if self . eat_keyword ( kw:: Loop ) {
1289
- self . parse_loop_expr ( None , self . prev_token . span , attrs)
1289
+ let sp = self . prev_token . span ;
1290
+ self . parse_loop_expr ( None , self . prev_token . span , attrs) . map_err ( |mut err| {
1291
+ err. span_label ( sp, "while parsing this `loop` expression" ) ;
1292
+ err
1293
+ } )
1290
1294
} else if self . eat_keyword ( kw:: Continue ) {
1291
1295
let kind = ExprKind :: Continue ( self . eat_label ( ) ) ;
1292
1296
Ok ( self . mk_expr ( lo. to ( self . prev_token . span ) , kind, attrs) )
1293
1297
} else if self . eat_keyword ( kw:: Match ) {
1294
1298
let match_sp = self . prev_token . span ;
1295
1299
self . parse_match_expr ( attrs) . map_err ( |mut err| {
1296
- err. span_label ( match_sp, "while parsing this match expression" ) ;
1300
+ err. span_label ( match_sp, "while parsing this ` match` expression" ) ;
1297
1301
err
1298
1302
} )
1299
1303
} else if self . eat_keyword ( kw:: Unsafe ) {
1304
+ let sp = self . prev_token . span ;
1300
1305
self . parse_block_expr ( None , lo, BlockCheckMode :: Unsafe ( ast:: UserProvided ) , attrs)
1306
+ . map_err ( |mut err| {
1307
+ err. span_label ( sp, "while parsing this `unsafe` expression" ) ;
1308
+ err
1309
+ } )
1301
1310
} else if self . check_inline_const ( 0 ) {
1302
1311
self . parse_const_block ( lo. to ( self . token . span ) , false )
1303
1312
} else if self . is_do_catch_block ( ) {
@@ -2160,7 +2169,12 @@ impl<'a> Parser<'a> {
2160
2169
/// The `let` token has already been eaten.
2161
2170
fn parse_let_expr ( & mut self , attrs : AttrVec ) -> PResult < ' a , P < Expr > > {
2162
2171
let lo = self . prev_token . span ;
2163
- let pat = self . parse_pat_allow_top_alt ( None , RecoverComma :: Yes , RecoverColon :: Yes ) ?;
2172
+ let pat = self . parse_pat_allow_top_alt (
2173
+ None ,
2174
+ RecoverComma :: Yes ,
2175
+ RecoverColon :: Yes ,
2176
+ CommaRecoveryMode :: LikelyTuple ,
2177
+ ) ?;
2164
2178
self . expect ( & token:: Eq ) ?;
2165
2179
let expr = self . with_res ( self . restrictions | Restrictions :: NO_STRUCT_LITERAL , |this| {
2166
2180
this. parse_assoc_expr_with ( 1 + prec_let_scrutinee_needs_par ( ) , None . into ( ) )
@@ -2223,7 +2237,12 @@ impl<'a> Parser<'a> {
2223
2237
_ => None ,
2224
2238
} ;
2225
2239
2226
- let pat = self . parse_pat_allow_top_alt ( None , RecoverComma :: Yes , RecoverColon :: Yes ) ?;
2240
+ let pat = self . parse_pat_allow_top_alt (
2241
+ None ,
2242
+ RecoverComma :: Yes ,
2243
+ RecoverColon :: Yes ,
2244
+ CommaRecoveryMode :: LikelyTuple ,
2245
+ ) ?;
2227
2246
if !self . eat_keyword ( kw:: In ) {
2228
2247
self . error_missing_in_for_loop ( ) ;
2229
2248
}
@@ -2266,8 +2285,15 @@ impl<'a> Parser<'a> {
2266
2285
lo : Span ,
2267
2286
mut attrs : AttrVec ,
2268
2287
) -> PResult < ' a , P < Expr > > {
2269
- let cond = self . parse_cond_expr ( ) ?;
2270
- let ( iattrs, body) = self . parse_inner_attrs_and_block ( ) ?;
2288
+ let cond = self . parse_cond_expr ( ) . map_err ( |mut err| {
2289
+ err. span_label ( lo, "while parsing the condition of this `while` expression" ) ;
2290
+ err
2291
+ } ) ?;
2292
+ let ( iattrs, body) = self . parse_inner_attrs_and_block ( ) . map_err ( |mut err| {
2293
+ err. span_label ( lo, "while parsing the body of this `while` expression" ) ;
2294
+ err. span_label ( cond. span , "this `while` condition successfully parsed" ) ;
2295
+ err
2296
+ } ) ?;
2271
2297
attrs. extend ( iattrs) ;
2272
2298
Ok ( self . mk_expr ( lo. to ( self . prev_token . span ) , ExprKind :: While ( cond, body, opt_label) , attrs) )
2273
2299
}
@@ -2284,7 +2310,7 @@ impl<'a> Parser<'a> {
2284
2310
Ok ( self . mk_expr ( lo. to ( self . prev_token . span ) , ExprKind :: Loop ( body, opt_label) , attrs) )
2285
2311
}
2286
2312
2287
- fn eat_label ( & mut self ) -> Option < Label > {
2313
+ crate fn eat_label ( & mut self ) -> Option < Label > {
2288
2314
self . token . lifetime ( ) . map ( |ident| {
2289
2315
self . bump ( ) ;
2290
2316
Label { ident }
@@ -2305,7 +2331,12 @@ impl<'a> Parser<'a> {
2305
2331
Applicability :: MaybeIncorrect , // speculative
2306
2332
) ;
2307
2333
}
2308
- return Err ( e) ;
2334
+ if self . maybe_recover_unexpected_block_label ( ) {
2335
+ e. cancel ( ) ;
2336
+ self . bump ( ) ;
2337
+ } else {
2338
+ return Err ( e) ;
2339
+ }
2309
2340
}
2310
2341
attrs. extend ( self . parse_inner_attributes ( ) ?) ;
2311
2342
@@ -2441,7 +2472,12 @@ impl<'a> Parser<'a> {
2441
2472
let attrs = self . parse_outer_attributes ( ) ?;
2442
2473
self . collect_tokens_trailing_token ( attrs, ForceCollect :: No , |this, attrs| {
2443
2474
let lo = this. token . span ;
2444
- let pat = this. parse_pat_allow_top_alt ( None , RecoverComma :: Yes , RecoverColon :: Yes ) ?;
2475
+ let pat = this. parse_pat_allow_top_alt (
2476
+ None ,
2477
+ RecoverComma :: Yes ,
2478
+ RecoverColon :: Yes ,
2479
+ CommaRecoveryMode :: EitherTupleOrPipe ,
2480
+ ) ?;
2445
2481
let guard = if this. eat_keyword ( kw:: If ) {
2446
2482
let if_span = this. prev_token . span ;
2447
2483
let cond = this. parse_expr ( ) ?;
0 commit comments