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 ,
@@ -1269,18 +1269,27 @@ impl<'a> Parser<'a> {
1269
1269
} else if let Some ( label) = self . eat_label ( ) {
1270
1270
self . parse_labeled_expr ( label, attrs, true )
1271
1271
} else if self . eat_keyword ( kw:: Loop ) {
1272
- self . parse_loop_expr ( None , self . prev_token . span , attrs)
1272
+ let sp = self . prev_token . span ;
1273
+ self . parse_loop_expr ( None , self . prev_token . span , attrs) . map_err ( |mut err| {
1274
+ err. span_label ( sp, "while parsing this `loop` expression" ) ;
1275
+ err
1276
+ } )
1273
1277
} else if self . eat_keyword ( kw:: Continue ) {
1274
1278
let kind = ExprKind :: Continue ( self . eat_label ( ) ) ;
1275
1279
Ok ( self . mk_expr ( lo. to ( self . prev_token . span ) , kind, attrs) )
1276
1280
} else if self . eat_keyword ( kw:: Match ) {
1277
1281
let match_sp = self . prev_token . span ;
1278
1282
self . parse_match_expr ( attrs) . map_err ( |mut err| {
1279
- err. span_label ( match_sp, "while parsing this match expression" ) ;
1283
+ err. span_label ( match_sp, "while parsing this ` match` expression" ) ;
1280
1284
err
1281
1285
} )
1282
1286
} else if self . eat_keyword ( kw:: Unsafe ) {
1287
+ let sp = self . prev_token . span ;
1283
1288
self . parse_block_expr ( None , lo, BlockCheckMode :: Unsafe ( ast:: UserProvided ) , attrs)
1289
+ . map_err ( |mut err| {
1290
+ err. span_label ( sp, "while parsing this `unsafe` expression" ) ;
1291
+ err
1292
+ } )
1284
1293
} else if self . check_inline_const ( 0 ) {
1285
1294
self . parse_const_block ( lo. to ( self . token . span ) , false )
1286
1295
} else if self . is_do_catch_block ( ) {
@@ -2110,7 +2119,12 @@ impl<'a> Parser<'a> {
2110
2119
/// The `let` token has already been eaten.
2111
2120
fn parse_let_expr ( & mut self , attrs : AttrVec ) -> PResult < ' a , P < Expr > > {
2112
2121
let lo = self . prev_token . span ;
2113
- let pat = self . parse_pat_allow_top_alt ( None , RecoverComma :: Yes , RecoverColon :: Yes ) ?;
2122
+ let pat = self . parse_pat_allow_top_alt (
2123
+ None ,
2124
+ RecoverComma :: Yes ,
2125
+ RecoverColon :: Yes ,
2126
+ CommaRecoveryMode :: LikelyTuple ,
2127
+ ) ?;
2114
2128
self . expect ( & token:: Eq ) ?;
2115
2129
let expr = self . with_res ( self . restrictions | Restrictions :: NO_STRUCT_LITERAL , |this| {
2116
2130
this. parse_assoc_expr_with ( 1 + prec_let_scrutinee_needs_par ( ) , None . into ( ) )
@@ -2173,7 +2187,12 @@ impl<'a> Parser<'a> {
2173
2187
_ => None ,
2174
2188
} ;
2175
2189
2176
- let pat = self . parse_pat_allow_top_alt ( None , RecoverComma :: Yes , RecoverColon :: Yes ) ?;
2190
+ let pat = self . parse_pat_allow_top_alt (
2191
+ None ,
2192
+ RecoverComma :: Yes ,
2193
+ RecoverColon :: Yes ,
2194
+ CommaRecoveryMode :: LikelyTuple ,
2195
+ ) ?;
2177
2196
if !self . eat_keyword ( kw:: In ) {
2178
2197
self . error_missing_in_for_loop ( ) ;
2179
2198
}
@@ -2216,8 +2235,15 @@ impl<'a> Parser<'a> {
2216
2235
lo : Span ,
2217
2236
mut attrs : AttrVec ,
2218
2237
) -> PResult < ' a , P < Expr > > {
2219
- let cond = self . parse_cond_expr ( ) ?;
2220
- let ( iattrs, body) = self . parse_inner_attrs_and_block ( ) ?;
2238
+ let cond = self . parse_cond_expr ( ) . map_err ( |mut err| {
2239
+ err. span_label ( lo, "while parsing the condition of this `while` expression" ) ;
2240
+ err
2241
+ } ) ?;
2242
+ let ( iattrs, body) = self . parse_inner_attrs_and_block ( ) . map_err ( |mut err| {
2243
+ err. span_label ( lo, "while parsing the body of this `while` expression" ) ;
2244
+ err. span_label ( cond. span , "this `while` condition successfully parsed" ) ;
2245
+ err
2246
+ } ) ?;
2221
2247
attrs. extend ( iattrs) ;
2222
2248
Ok ( self . mk_expr ( lo. to ( self . prev_token . span ) , ExprKind :: While ( cond, body, opt_label) , attrs) )
2223
2249
}
@@ -2234,7 +2260,7 @@ impl<'a> Parser<'a> {
2234
2260
Ok ( self . mk_expr ( lo. to ( self . prev_token . span ) , ExprKind :: Loop ( body, opt_label) , attrs) )
2235
2261
}
2236
2262
2237
- fn eat_label ( & mut self ) -> Option < Label > {
2263
+ crate fn eat_label ( & mut self ) -> Option < Label > {
2238
2264
self . token . lifetime ( ) . map ( |ident| {
2239
2265
self . bump ( ) ;
2240
2266
Label { ident }
@@ -2255,7 +2281,12 @@ impl<'a> Parser<'a> {
2255
2281
Applicability :: MaybeIncorrect , // speculative
2256
2282
) ;
2257
2283
}
2258
- return Err ( e) ;
2284
+ if self . maybe_recover_unexpected_block_label ( ) {
2285
+ e. cancel ( ) ;
2286
+ self . bump ( ) ;
2287
+ } else {
2288
+ return Err ( e) ;
2289
+ }
2259
2290
}
2260
2291
attrs. extend ( self . parse_inner_attributes ( ) ?) ;
2261
2292
@@ -2380,7 +2411,12 @@ impl<'a> Parser<'a> {
2380
2411
let attrs = self . parse_outer_attributes ( ) ?;
2381
2412
self . collect_tokens_trailing_token ( attrs, ForceCollect :: No , |this, attrs| {
2382
2413
let lo = this. token . span ;
2383
- let pat = this. parse_pat_allow_top_alt ( None , RecoverComma :: Yes , RecoverColon :: Yes ) ?;
2414
+ let pat = this. parse_pat_allow_top_alt (
2415
+ None ,
2416
+ RecoverComma :: Yes ,
2417
+ RecoverColon :: Yes ,
2418
+ CommaRecoveryMode :: EitherTupleOrPipe ,
2419
+ ) ?;
2384
2420
let guard = if this. eat_keyword ( kw:: If ) {
2385
2421
let if_span = this. prev_token . span ;
2386
2422
let cond = this. parse_expr ( ) ?;
0 commit comments