@@ -391,10 +391,26 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
391
391
arms : & [ MatchArm < ' p , ' tcx > ] ,
392
392
scrut_ty : Ty < ' tcx > ,
393
393
) -> Result < UsefulnessReport < ' p , ' tcx > , ErrorGuaranteed > {
394
- rustc_pattern_analysis:: analyze_match ( & cx, & arms, scrut_ty) . map_err ( |err| {
395
- self . error = Err ( err) ;
396
- err
397
- } )
394
+ let report =
395
+ rustc_pattern_analysis:: analyze_match ( & cx, & arms, scrut_ty) . map_err ( |err| {
396
+ self . error = Err ( err) ;
397
+ err
398
+ } ) ?;
399
+
400
+ // Warn unreachable subpatterns.
401
+ for ( arm, is_useful) in report. arm_usefulness . iter ( ) {
402
+ if let Usefulness :: Useful ( redundant_subpats) = is_useful
403
+ && !redundant_subpats. is_empty ( )
404
+ {
405
+ let mut redundant_subpats = redundant_subpats. clone ( ) ;
406
+ // Emit lints in the order in which they occur in the file.
407
+ redundant_subpats. sort_unstable_by_key ( |pat| pat. data ( ) . unwrap ( ) . span ) ;
408
+ for pat in redundant_subpats {
409
+ report_unreachable_pattern ( cx, arm. arm_data , pat. data ( ) . unwrap ( ) . span , None )
410
+ }
411
+ }
412
+ }
413
+ Ok ( report)
398
414
}
399
415
400
416
#[ instrument( level = "trace" , skip( self ) ) ]
@@ -567,7 +583,6 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
567
583
) -> Result < RefutableFlag , ErrorGuaranteed > {
568
584
let ( cx, report) = self . analyze_binding ( pat, Refutable , scrut) ?;
569
585
// Report if the pattern is unreachable, which can only occur when the type is uninhabited.
570
- // This also reports unreachable sub-patterns.
571
586
report_arm_reachability ( & cx, & report) ;
572
587
// If the list of witnesses is empty, the match is exhaustive, i.e. the `if let` pattern is
573
588
// irrefutable.
@@ -837,39 +852,30 @@ fn report_irrefutable_let_patterns(
837
852
}
838
853
}
839
854
855
+ /// Report unreachable arms, if any.
856
+ fn report_unreachable_pattern < ' p , ' tcx > (
857
+ cx : & MatchCheckCtxt < ' p , ' tcx > ,
858
+ hir_id : HirId ,
859
+ span : Span ,
860
+ catchall : Option < Span > ,
861
+ ) {
862
+ cx. tcx . emit_spanned_lint (
863
+ UNREACHABLE_PATTERNS ,
864
+ hir_id,
865
+ span,
866
+ UnreachablePattern { span : if catchall. is_some ( ) { Some ( span) } else { None } , catchall } ,
867
+ ) ;
868
+ }
869
+
840
870
/// Report unreachable arms, if any.
841
871
fn report_arm_reachability < ' p , ' tcx > (
842
872
cx : & MatchCheckCtxt < ' p , ' tcx > ,
843
873
report : & UsefulnessReport < ' p , ' tcx > ,
844
874
) {
845
- let report_unreachable_pattern = |span, hir_id, catchall : Option < Span > | {
846
- cx. tcx . emit_spanned_lint (
847
- UNREACHABLE_PATTERNS ,
848
- hir_id,
849
- span,
850
- UnreachablePattern {
851
- span : if catchall. is_some ( ) { Some ( span) } else { None } ,
852
- catchall,
853
- } ,
854
- ) ;
855
- } ;
856
-
857
875
let mut catchall = None ;
858
876
for ( arm, is_useful) in report. arm_usefulness . iter ( ) {
859
- match is_useful {
860
- Usefulness :: Redundant => {
861
- report_unreachable_pattern ( arm. pat . data ( ) . unwrap ( ) . span , arm. arm_data , catchall)
862
- }
863
- Usefulness :: Useful ( redundant_subpats) if redundant_subpats. is_empty ( ) => { }
864
- // The arm is reachable, but contains redundant subpatterns (from or-patterns).
865
- Usefulness :: Useful ( redundant_subpats) => {
866
- let mut redundant_subpats = redundant_subpats. clone ( ) ;
867
- // Emit lints in the order in which they occur in the file.
868
- redundant_subpats. sort_unstable_by_key ( |pat| pat. data ( ) . unwrap ( ) . span ) ;
869
- for pat in redundant_subpats {
870
- report_unreachable_pattern ( pat. data ( ) . unwrap ( ) . span , arm. arm_data , None ) ;
871
- }
872
- }
877
+ if matches ! ( is_useful, Usefulness :: Redundant ) {
878
+ report_unreachable_pattern ( cx, arm. arm_data , arm. pat . data ( ) . unwrap ( ) . span , catchall)
873
879
}
874
880
if !arm. has_guard && catchall. is_none ( ) && pat_is_catchall ( arm. pat ) {
875
881
catchall = Some ( arm. pat . data ( ) . unwrap ( ) . span ) ;
0 commit comments