@@ -26,8 +26,11 @@ use rustc_session::Session;
2626use rustc_span:: hygiene:: DesugaringKind ;
2727use rustc_span:: Span ;
2828
29- pub ( crate ) fn check_match ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) {
30- let Ok ( ( thir, expr) ) = tcx. thir_body ( def_id) else { return } ;
29+ pub ( crate ) fn check_match ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> Result < ( ) , ErrorGuaranteed > {
30+ let ( thir, expr) = match tcx. thir_body ( def_id) {
31+ Ok ( ( thir, expr) ) => ( thir, expr) ,
32+ Err ( e) => return Err ( e) ,
33+ } ;
3134 let thir = thir. borrow ( ) ;
3235 let pattern_arena = TypedArena :: default ( ) ;
3336 let mut visitor = MatchVisitor {
@@ -37,13 +40,18 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
3740 lint_level : tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ,
3841 let_source : LetSource :: None ,
3942 pattern_arena : & pattern_arena,
43+ errors : vec ! [ ] ,
4044 } ;
4145 visitor. visit_expr ( & thir[ expr] ) ;
46+ if let Some ( e) = visitor. errors . first ( ) {
47+ return Err ( * e) ;
48+ }
4249 for param in thir. params . iter ( ) {
4350 if let Some ( box ref pattern) = param. pat {
44- visitor. check_irrefutable ( pattern, "function argument" , None ) ;
51+ visitor. check_irrefutable ( pattern, "function argument" , None ) ? ;
4552 }
4653 }
54+ Ok ( ( ) )
4755}
4856
4957fn create_e0004 (
@@ -77,6 +85,7 @@ struct MatchVisitor<'a, 'p, 'tcx> {
7785 lint_level : HirId ,
7886 let_source : LetSource ,
7987 pattern_arena : & ' p TypedArena < DeconstructedPat < ' p , ' tcx > > ,
88+ errors : Vec < ErrorGuaranteed > ,
8089}
8190
8291impl < ' a , ' tcx > Visitor < ' a , ' tcx > for MatchVisitor < ' a , ' _ , ' tcx > {
@@ -139,7 +148,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
139148 Some ( DesugaringKind :: Await ) => hir:: MatchSource :: AwaitDesugar ,
140149 _ => hir:: MatchSource :: Normal ,
141150 } ;
142- self . check_match ( scrutinee, arms, source, ex. span ) ;
151+ if let Err ( e) = self . check_match ( scrutinee, arms, source, ex. span ) {
152+ self . errors . push ( e)
153+ }
143154 }
144155 ExprKind :: Let { box ref pat, expr } => {
145156 self . check_let ( pat, expr, self . let_source , ex. span ) ;
@@ -166,8 +177,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
166177 self . check_let ( pattern, initializer, LetSource :: LetElse , span) ;
167178 }
168179
169- if else_block. is_none ( ) {
170- self . check_irrefutable ( pattern, "local binding" , Some ( span) ) ;
180+ if else_block. is_none ( )
181+ && let Err ( e) = self . check_irrefutable ( pattern, "local binding" , Some ( span) ) {
182+ self . errors . push ( e) ;
171183 }
172184 }
173185 _ => { }
@@ -226,7 +238,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
226238 arms : & [ ArmId ] ,
227239 source : hir:: MatchSource ,
228240 expr_span : Span ,
229- ) {
241+ ) -> Result < ( ) , ErrorGuaranteed > {
230242 let mut cx = self . new_cx ( self . lint_level , true ) ;
231243
232244 for & arm in arms {
@@ -274,13 +286,14 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
274286 debug_assert_eq ! ( pat. span. desugaring_kind( ) , Some ( DesugaringKind :: ForLoop ) ) ;
275287 let PatKind :: Variant { ref subpatterns, .. } = pat. kind else { bug ! ( ) } ;
276288 let [ pat_field] = & subpatterns[ ..] else { bug ! ( ) } ;
277- self . check_irrefutable ( & pat_field. pattern , "`for` loop binding" , None ) ;
289+ self . check_irrefutable ( & pat_field. pattern , "`for` loop binding" , None ) ? ;
278290 } else {
279- non_exhaustive_match (
291+ return Err ( non_exhaustive_match (
280292 & cx, self . thir , scrut_ty, scrut. span , witnesses, arms, expr_span,
281- ) ;
293+ ) ) ;
282294 }
283295 }
296+ Ok ( ( ) )
284297 }
285298
286299 fn check_let_reachability (
@@ -409,7 +422,12 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
409422 }
410423
411424 #[ instrument( level = "trace" , skip( self ) ) ]
412- fn check_irrefutable ( & self , pat : & Pat < ' tcx > , origin : & str , sp : Option < Span > ) {
425+ fn check_irrefutable (
426+ & self ,
427+ pat : & Pat < ' tcx > ,
428+ origin : & str ,
429+ sp : Option < Span > ,
430+ ) -> Result < ( ) , ErrorGuaranteed > {
413431 let mut cx = self . new_cx ( self . lint_level , false ) ;
414432
415433 let pattern = self . lower_pattern ( & mut cx, pat) ;
@@ -423,7 +441,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
423441 if witnesses. is_empty ( ) {
424442 // The pattern is irrefutable.
425443 self . check_patterns ( pat, Irrefutable ) ;
426- return ;
444+ return Ok ( ( ) ) ;
427445 }
428446
429447 let inform = sp. is_some ( ) . then_some ( Inform ) ;
@@ -478,7 +496,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
478496 AdtDefinedHere { adt_def_span, ty, variants }
479497 } ;
480498
481- self . tcx . sess . emit_err ( PatternNotCovered {
499+ Err ( self . tcx . sess . emit_err ( PatternNotCovered {
482500 span : pat. span ,
483501 origin,
484502 uncovered : Uncovered :: new ( pat. span , & cx, witnesses) ,
@@ -489,7 +507,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
489507 let_suggestion,
490508 misc_suggestion,
491509 adt_defined_here,
492- } ) ;
510+ } ) )
493511 }
494512}
495513
@@ -631,7 +649,7 @@ fn non_exhaustive_match<'p, 'tcx>(
631649 witnesses : Vec < DeconstructedPat < ' p , ' tcx > > ,
632650 arms : & [ ArmId ] ,
633651 expr_span : Span ,
634- ) {
652+ ) -> ErrorGuaranteed {
635653 let is_empty_match = arms. is_empty ( ) ;
636654 let non_empty_enum = match scrut_ty. kind ( ) {
637655 ty:: Adt ( def, _) => def. is_enum ( ) && !def. variants ( ) . is_empty ( ) ,
@@ -643,13 +661,12 @@ fn non_exhaustive_match<'p, 'tcx>(
643661 let pattern;
644662 let patterns_len;
645663 if is_empty_match && !non_empty_enum {
646- cx. tcx . sess . emit_err ( NonExhaustivePatternsTypeNotEmpty {
664+ return cx. tcx . sess . emit_err ( NonExhaustivePatternsTypeNotEmpty {
647665 cx,
648666 expr_span,
649667 span : sp,
650668 ty : scrut_ty,
651669 } ) ;
652- return ;
653670 } else {
654671 // FIXME: migration of this diagnostic will require list support
655672 let joined_patterns = joined_uncovered_patterns ( cx, & witnesses) ;
@@ -800,7 +817,7 @@ fn non_exhaustive_match<'p, 'tcx>(
800817 } else {
801818 err. help ( & msg) ;
802819 }
803- err. emit ( ) ;
820+ err. emit ( )
804821}
805822
806823pub ( crate ) fn joined_uncovered_patterns < ' p , ' tcx > (
0 commit comments