@@ -81,6 +81,9 @@ struct MatchVisitor<'a, 'p, 'tcx> {
8181 lint_level : HirId ,
8282 let_source : LetSource ,
8383 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.
8487 error : Result < ( ) , ErrorGuaranteed > ,
8588}
8689
@@ -211,11 +214,16 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
211214 }
212215
213216 fn lower_pattern (
214- & self ,
215- cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
217+ & mut self ,
218+ cx : & MatchCheckCtxt < ' p , ' tcx > ,
216219 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+ }
219227 }
220228
221229 fn new_cx ( & self , hir_id : HirId , refutable : bool ) -> MatchCheckCtxt < ' p , ' tcx > {
@@ -233,13 +241,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
233241 if let LetSource :: None = source {
234242 return ;
235243 }
236- if let Err ( err) = pat. pat_error_reported ( ) {
237- self . error = Err ( err) ;
238- return ;
239- }
240244 self . check_patterns ( pat, Refutable ) ;
241245 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 } ;
243247 self . check_let_reachability ( & mut cx, self . lint_level , source, tpat, span) ;
244248 }
245249
@@ -252,31 +256,22 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
252256 ) {
253257 let mut cx = self . new_cx ( self . lint_level , true ) ;
254258
259+ let mut tarms = Vec :: with_capacity ( arms. len ( ) ) ;
255260 for & arm in arms {
256261 // Check the arm for some things unrelated to exhaustiveness.
257262 let arm = & self . thir . arms [ arm] ;
258263 self . with_lint_level ( arm. lint_level , |this| {
259264 this. check_patterns ( & arm. pattern , Refutable ) ;
260265 } ) ;
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) ;
265273 }
266274
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-
280275 let scrut = & self . thir [ scrut] ;
281276 let scrut_ty = scrut. ty ;
282277 let report = compute_match_usefulness ( & cx, & tarms, self . lint_level , scrut_ty, scrut. span ) ;
@@ -340,7 +335,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
340335 // and record chain members that aren't let exprs.
341336 let mut chain_refutabilities = Vec :: new ( ) ;
342337
343- let mut error = Ok ( ( ) ) ;
338+ let mut got_lowering_error = false ;
344339 let mut next_expr = Some ( expr) ;
345340 while let Some ( mut expr) = next_expr {
346341 while let ExprKind :: Scope { value, lint_level, .. } = expr. kind {
@@ -368,14 +363,13 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
368363 }
369364 let value = match expr. kind {
370365 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) {
377368 let refutable = !is_let_irrefutable ( & mut ncx, expr_lint_level, tpat) ;
378369 Some ( ( expr. span , refutable) )
370+ } else {
371+ got_lowering_error = true ;
372+ None
379373 }
380374 }
381375 _ => None ,
@@ -385,8 +379,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
385379 debug ! ( ?chain_refutabilities) ;
386380 chain_refutabilities. reverse ( ) ;
387381
388- if error. is_err ( ) {
389- self . error = error;
382+ if got_lowering_error {
390383 return ;
391384 }
392385
@@ -452,15 +445,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
452445
453446 #[ instrument( level = "trace" , skip( self ) ) ]
454447 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-
461448 let mut cx = self . new_cx ( self . lint_level , false ) ;
462449
463- let pattern = self . lower_pattern ( & mut cx, pat) ;
450+ let Ok ( pattern) = self . lower_pattern ( & mut cx, pat) else { return } ;
464451 let pattern_ty = pattern. ty ( ) ;
465452 let arm = MatchArm { pat : pattern, hir_id : self . lint_level , has_guard : false } ;
466453 let report =
0 commit comments