@@ -81,6 +81,9 @@ struct MatchVisitor<'a, 'p, 'tcx> {
81
81
lint_level : HirId ,
82
82
let_source : LetSource ,
83
83
pattern_arena : & ' p TypedArena < DeconstructedPat < ' p , ' tcx > > ,
84
+ /// Tracks if we encountered an error while checking this body. That the first function to
85
+ /// report it stores it here. Some functions return `Result` to allow callers to short-circuit
86
+ /// on error, but callers don't need to store it here again.
84
87
error : Result < ( ) , ErrorGuaranteed > ,
85
88
}
86
89
@@ -211,11 +214,16 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
211
214
}
212
215
213
216
fn lower_pattern (
214
- & self ,
215
- cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
217
+ & mut self ,
218
+ cx : & MatchCheckCtxt < ' p , ' tcx > ,
216
219
pattern : & Pat < ' tcx > ,
217
- ) -> & ' p DeconstructedPat < ' p , ' tcx > {
218
- cx. pattern_arena . alloc ( DeconstructedPat :: from_pat ( cx, & pattern) )
220
+ ) -> Result < & ' p DeconstructedPat < ' p , ' tcx > , ErrorGuaranteed > {
221
+ if let Err ( err) = pattern. pat_error_reported ( ) {
222
+ self . error = Err ( err) ;
223
+ Err ( err)
224
+ } else {
225
+ Ok ( cx. pattern_arena . alloc ( DeconstructedPat :: from_pat ( cx, pattern) ) )
226
+ }
219
227
}
220
228
221
229
fn new_cx ( & self , hir_id : HirId , refutable : bool ) -> MatchCheckCtxt < ' p , ' tcx > {
@@ -233,13 +241,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
233
241
if let LetSource :: None = source {
234
242
return ;
235
243
}
236
- if let Err ( err) = pat. pat_error_reported ( ) {
237
- self . error = Err ( err) ;
238
- return ;
239
- }
240
244
self . check_patterns ( pat, Refutable ) ;
241
245
let mut cx = self . new_cx ( self . lint_level , true ) ;
242
- let tpat = self . lower_pattern ( & mut cx, pat) ;
246
+ let Ok ( tpat) = self . lower_pattern ( & cx, pat) else { return } ;
243
247
self . check_let_reachability ( & mut cx, self . lint_level , source, tpat, span) ;
244
248
}
245
249
@@ -252,31 +256,22 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
252
256
) {
253
257
let mut cx = self . new_cx ( self . lint_level , true ) ;
254
258
259
+ let mut tarms = Vec :: with_capacity ( arms. len ( ) ) ;
255
260
for & arm in arms {
256
261
// Check the arm for some things unrelated to exhaustiveness.
257
262
let arm = & self . thir . arms [ arm] ;
258
263
self . with_lint_level ( arm. lint_level , |this| {
259
264
this. check_patterns ( & arm. pattern , Refutable ) ;
260
265
} ) ;
261
- if let Err ( err) = arm. pattern . pat_error_reported ( ) {
262
- self . error = Err ( err) ;
263
- return ;
264
- }
266
+ let hir_id = match arm. lint_level {
267
+ LintLevel :: Explicit ( hir_id) => hir_id,
268
+ LintLevel :: Inherited => self . lint_level ,
269
+ } ;
270
+ let Ok ( pat) = self . lower_pattern ( & mut cx, & arm. pattern ) else { return } ;
271
+ let arm = MatchArm { pat, hir_id, has_guard : arm. guard . is_some ( ) } ;
272
+ tarms. push ( arm) ;
265
273
}
266
274
267
- let tarms: Vec < _ > = arms
268
- . iter ( )
269
- . map ( |& arm| {
270
- let arm = & self . thir . arms [ arm] ;
271
- let hir_id = match arm. lint_level {
272
- LintLevel :: Explicit ( hir_id) => hir_id,
273
- LintLevel :: Inherited => self . lint_level ,
274
- } ;
275
- let pat = self . lower_pattern ( & mut cx, & arm. pattern ) ;
276
- MatchArm { pat, hir_id, has_guard : arm. guard . is_some ( ) }
277
- } )
278
- . collect ( ) ;
279
-
280
275
let scrut = & self . thir [ scrut] ;
281
276
let scrut_ty = scrut. ty ;
282
277
let report = compute_match_usefulness ( & cx, & tarms, self . lint_level , scrut_ty, scrut. span ) ;
@@ -340,7 +335,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
340
335
// and record chain members that aren't let exprs.
341
336
let mut chain_refutabilities = Vec :: new ( ) ;
342
337
343
- let mut error = Ok ( ( ) ) ;
338
+ let mut got_lowering_error = false ;
344
339
let mut next_expr = Some ( expr) ;
345
340
while let Some ( mut expr) = next_expr {
346
341
while let ExprKind :: Scope { value, lint_level, .. } = expr. kind {
@@ -368,14 +363,13 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
368
363
}
369
364
let value = match expr. kind {
370
365
ExprKind :: Let { box ref pat, expr : _ } => {
371
- if let Err ( err) = pat. pat_error_reported ( ) {
372
- error = Err ( err) ;
373
- None
374
- } else {
375
- let mut ncx = self . new_cx ( expr_lint_level, true ) ;
376
- let tpat = self . lower_pattern ( & mut ncx, pat) ;
366
+ let mut ncx = self . new_cx ( expr_lint_level, true ) ;
367
+ if let Ok ( tpat) = self . lower_pattern ( & mut ncx, pat) {
377
368
let refutable = !is_let_irrefutable ( & mut ncx, expr_lint_level, tpat) ;
378
369
Some ( ( expr. span , refutable) )
370
+ } else {
371
+ got_lowering_error = true ;
372
+ None
379
373
}
380
374
}
381
375
_ => None ,
@@ -385,8 +379,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
385
379
debug ! ( ?chain_refutabilities) ;
386
380
chain_refutabilities. reverse ( ) ;
387
381
388
- if error. is_err ( ) {
389
- self . error = error;
382
+ if got_lowering_error {
390
383
return ;
391
384
}
392
385
@@ -452,15 +445,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
452
445
453
446
#[ instrument( level = "trace" , skip( self ) ) ]
454
447
fn check_irrefutable ( & mut self , pat : & Pat < ' tcx > , origin : & str , sp : Option < Span > ) {
455
- // If we got errors while lowering, don't emit anything more.
456
- if let Err ( err) = pat. pat_error_reported ( ) {
457
- self . error = Err ( err) ;
458
- return ;
459
- }
460
-
461
448
let mut cx = self . new_cx ( self . lint_level , false ) ;
462
449
463
- let pattern = self . lower_pattern ( & mut cx, pat) ;
450
+ let Ok ( pattern) = self . lower_pattern ( & mut cx, pat) else { return } ;
464
451
let pattern_ty = pattern. ty ( ) ;
465
452
let arm = MatchArm { pat : pattern, hir_id : self . lint_level , has_guard : false } ;
466
453
let report =
0 commit comments