@@ -413,7 +413,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
413
413
// Emit lints in the order in which they occur in the file.
414
414
redundant_subpats. sort_unstable_by_key ( |( pat, _) | pat. data ( ) . span ) ;
415
415
for ( pat, explanation) in redundant_subpats {
416
- report_unreachable_pattern ( cx, arm. arm_data , pat, & explanation)
416
+ report_unreachable_pattern ( cx, arm. arm_data , pat, & explanation, None )
417
417
}
418
418
}
419
419
}
@@ -474,7 +474,11 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
474
474
hir:: MatchSource :: ForLoopDesugar
475
475
| hir:: MatchSource :: Postfix
476
476
| hir:: MatchSource :: Normal
477
- | hir:: MatchSource :: FormatArgs => report_arm_reachability ( & cx, & report) ,
477
+ | hir:: MatchSource :: FormatArgs => {
478
+ let suggest_removing_if_unreachable =
479
+ matches ! ( source, hir:: MatchSource :: Postfix | hir:: MatchSource :: Normal ) ;
480
+ report_arm_reachability ( & cx, & report, suggest_removing_if_unreachable) ;
481
+ }
478
482
// Unreachable patterns in try and await expressions occur when one of
479
483
// the arms are an uninhabited type. Which is OK.
480
484
hir:: MatchSource :: AwaitDesugar | hir:: MatchSource :: TryDesugar ( _) => { }
@@ -612,7 +616,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
612
616
refutability : RefutableFlag ,
613
617
scrut : Option < & Expr < ' tcx > > ,
614
618
) -> Result < ( PatCtxt < ' p , ' tcx > , UsefulnessReport < ' p , ' tcx > ) , ErrorGuaranteed > {
615
- let cx = self . new_cx ( refutability, None , scrut, pat. span ) ;
619
+ let pat_span = pat. span ;
620
+ let cx = self . new_cx ( refutability, None , scrut, pat_span) ;
616
621
let pat = self . lower_pattern ( & cx, pat) ?;
617
622
let arms = [ MatchArm { pat, arm_data : self . lint_level , has_guard : false } ] ;
618
623
let report = self . analyze_patterns ( & cx, & arms, pat. ty ( ) . inner ( ) ) ?;
@@ -626,7 +631,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
626
631
) -> Result < RefutableFlag , ErrorGuaranteed > {
627
632
let ( cx, report) = self . analyze_binding ( pat, Refutable , scrut) ?;
628
633
// Report if the pattern is unreachable, which can only occur when the type is uninhabited.
629
- report_arm_reachability ( & cx, & report) ;
634
+ report_arm_reachability ( & cx, & report, false ) ;
630
635
// If the list of witnesses is empty, the match is exhaustive, i.e. the `if let` pattern is
631
636
// irrefutable.
632
637
Ok ( if report. non_exhaustiveness_witnesses . is_empty ( ) { Irrefutable } else { Refutable } )
@@ -916,6 +921,7 @@ fn report_unreachable_pattern<'p, 'tcx>(
916
921
hir_id : HirId ,
917
922
pat : & DeconstructedPat < ' p , ' tcx > ,
918
923
explanation : & RedundancyExplanation < ' p , ' tcx > ,
924
+ suggest_remove : Option < Span > ,
919
925
) {
920
926
let pat_span = pat. data ( ) . span ;
921
927
let mut lint = UnreachablePattern {
@@ -924,6 +930,7 @@ fn report_unreachable_pattern<'p, 'tcx>(
924
930
covered_by_catchall : None ,
925
931
covered_by_one : None ,
926
932
covered_by_many : None ,
933
+ suggest_remove,
927
934
} ;
928
935
match explanation. covered_by . as_slice ( ) {
929
936
[ ] => {
@@ -964,10 +971,28 @@ fn report_unreachable_pattern<'p, 'tcx>(
964
971
}
965
972
966
973
/// Report unreachable arms, if any.
967
- fn report_arm_reachability < ' p , ' tcx > ( cx : & PatCtxt < ' p , ' tcx > , report : & UsefulnessReport < ' p , ' tcx > ) {
974
+ fn report_arm_reachability < ' p , ' tcx > (
975
+ cx : & PatCtxt < ' p , ' tcx > ,
976
+ report : & UsefulnessReport < ' p , ' tcx > ,
977
+ is_match_arm : bool ,
978
+ ) {
979
+ let sm = cx. tcx . sess . source_map ( ) ;
968
980
for ( arm, is_useful) in report. arm_usefulness . iter ( ) {
969
981
if let Usefulness :: Redundant ( explanation) = is_useful {
970
- report_unreachable_pattern ( cx, arm. arm_data , arm. pat , explanation)
982
+ let hir_id = arm. arm_data ;
983
+ let arm_span = cx. tcx . hir ( ) . span ( hir_id) ;
984
+ let suggest_remove = if is_match_arm {
985
+ // If the arm is followed by a comma, extend the span to include it.
986
+ let with_whitespace = sm. span_extend_while_whitespace ( arm_span) ;
987
+ if let Some ( comma) = sm. span_look_ahead ( with_whitespace, "," , Some ( 1 ) ) {
988
+ Some ( arm_span. to ( comma) )
989
+ } else {
990
+ Some ( arm_span)
991
+ }
992
+ } else {
993
+ None
994
+ } ;
995
+ report_unreachable_pattern ( cx, hir_id, arm. pat , explanation, suggest_remove)
971
996
}
972
997
}
973
998
}
0 commit comments