@@ -26,8 +26,11 @@ use rustc_session::Session;
26
26
use rustc_span:: hygiene:: DesugaringKind ;
27
27
use rustc_span:: Span ;
28
28
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
+ } ;
31
34
let thir = thir. borrow ( ) ;
32
35
let pattern_arena = TypedArena :: default ( ) ;
33
36
let mut visitor = MatchVisitor {
@@ -37,13 +40,18 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) {
37
40
lint_level : tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ,
38
41
let_source : LetSource :: None ,
39
42
pattern_arena : & pattern_arena,
43
+ errors : vec ! [ ] ,
40
44
} ;
41
45
visitor. visit_expr ( & thir[ expr] ) ;
46
+ if let Some ( e) = visitor. errors . first ( ) {
47
+ return Err ( * e) ;
48
+ }
42
49
for param in thir. params . iter ( ) {
43
50
if let Some ( box ref pattern) = param. pat {
44
- visitor. check_irrefutable ( pattern, "function argument" , None ) ;
51
+ visitor. check_irrefutable ( pattern, "function argument" , None ) ? ;
45
52
}
46
53
}
54
+ Ok ( ( ) )
47
55
}
48
56
49
57
fn create_e0004 (
@@ -77,6 +85,7 @@ struct MatchVisitor<'a, 'p, 'tcx> {
77
85
lint_level : HirId ,
78
86
let_source : LetSource ,
79
87
pattern_arena : & ' p TypedArena < DeconstructedPat < ' p , ' tcx > > ,
88
+ errors : Vec < ErrorGuaranteed > ,
80
89
}
81
90
82
91
impl < ' a , ' tcx > Visitor < ' a , ' tcx > for MatchVisitor < ' a , ' _ , ' tcx > {
@@ -139,7 +148,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
139
148
Some ( DesugaringKind :: Await ) => hir:: MatchSource :: AwaitDesugar ,
140
149
_ => hir:: MatchSource :: Normal ,
141
150
} ;
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
+ }
143
154
}
144
155
ExprKind :: Let { box ref pat, expr } => {
145
156
self . check_let ( pat, expr, self . let_source , ex. span ) ;
@@ -166,8 +177,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
166
177
self . check_let ( pattern, initializer, LetSource :: LetElse , span) ;
167
178
}
168
179
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) ;
171
183
}
172
184
}
173
185
_ => { }
@@ -226,7 +238,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
226
238
arms : & [ ArmId ] ,
227
239
source : hir:: MatchSource ,
228
240
expr_span : Span ,
229
- ) {
241
+ ) -> Result < ( ) , ErrorGuaranteed > {
230
242
let mut cx = self . new_cx ( self . lint_level , true ) ;
231
243
232
244
for & arm in arms {
@@ -274,13 +286,14 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
274
286
debug_assert_eq ! ( pat. span. desugaring_kind( ) , Some ( DesugaringKind :: ForLoop ) ) ;
275
287
let PatKind :: Variant { ref subpatterns, .. } = pat. kind else { bug ! ( ) } ;
276
288
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 ) ? ;
278
290
} else {
279
- non_exhaustive_match (
291
+ return Err ( non_exhaustive_match (
280
292
& cx, self . thir , scrut_ty, scrut. span , witnesses, arms, expr_span,
281
- ) ;
293
+ ) ) ;
282
294
}
283
295
}
296
+ Ok ( ( ) )
284
297
}
285
298
286
299
fn check_let_reachability (
@@ -409,7 +422,12 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
409
422
}
410
423
411
424
#[ 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 > {
413
431
let mut cx = self . new_cx ( self . lint_level , false ) ;
414
432
415
433
let pattern = self . lower_pattern ( & mut cx, pat) ;
@@ -423,7 +441,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
423
441
if witnesses. is_empty ( ) {
424
442
// The pattern is irrefutable.
425
443
self . check_patterns ( pat, Irrefutable ) ;
426
- return ;
444
+ return Ok ( ( ) ) ;
427
445
}
428
446
429
447
let inform = sp. is_some ( ) . then_some ( Inform ) ;
@@ -478,7 +496,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
478
496
AdtDefinedHere { adt_def_span, ty, variants }
479
497
} ;
480
498
481
- self . tcx . sess . emit_err ( PatternNotCovered {
499
+ Err ( self . tcx . sess . emit_err ( PatternNotCovered {
482
500
span : pat. span ,
483
501
origin,
484
502
uncovered : Uncovered :: new ( pat. span , & cx, witnesses) ,
@@ -489,7 +507,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
489
507
let_suggestion,
490
508
misc_suggestion,
491
509
adt_defined_here,
492
- } ) ;
510
+ } ) )
493
511
}
494
512
}
495
513
@@ -631,7 +649,7 @@ fn non_exhaustive_match<'p, 'tcx>(
631
649
witnesses : Vec < DeconstructedPat < ' p , ' tcx > > ,
632
650
arms : & [ ArmId ] ,
633
651
expr_span : Span ,
634
- ) {
652
+ ) -> ErrorGuaranteed {
635
653
let is_empty_match = arms. is_empty ( ) ;
636
654
let non_empty_enum = match scrut_ty. kind ( ) {
637
655
ty:: Adt ( def, _) => def. is_enum ( ) && !def. variants ( ) . is_empty ( ) ,
@@ -643,13 +661,12 @@ fn non_exhaustive_match<'p, 'tcx>(
643
661
let pattern;
644
662
let patterns_len;
645
663
if is_empty_match && !non_empty_enum {
646
- cx. tcx . sess . emit_err ( NonExhaustivePatternsTypeNotEmpty {
664
+ return cx. tcx . sess . emit_err ( NonExhaustivePatternsTypeNotEmpty {
647
665
cx,
648
666
expr_span,
649
667
span : sp,
650
668
ty : scrut_ty,
651
669
} ) ;
652
- return ;
653
670
} else {
654
671
// FIXME: migration of this diagnostic will require list support
655
672
let joined_patterns = joined_uncovered_patterns ( cx, & witnesses) ;
@@ -800,7 +817,7 @@ fn non_exhaustive_match<'p, 'tcx>(
800
817
} else {
801
818
err. help ( & msg) ;
802
819
}
803
- err. emit ( ) ;
820
+ err. emit ( )
804
821
}
805
822
806
823
pub ( crate ) fn joined_uncovered_patterns < ' p , ' tcx > (
0 commit comments