@@ -413,7 +413,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
413413 // Emit lints in the order in which they occur in the file.
414414 redundant_subpats. sort_unstable_by_key ( |( pat, _) | pat. data ( ) . span ) ;
415415 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 )
417417 }
418418 }
419419 }
@@ -474,7 +474,11 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
474474 hir:: MatchSource :: ForLoopDesugar
475475 | hir:: MatchSource :: Postfix
476476 | 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+ }
478482 // Unreachable patterns in try and await expressions occur when one of
479483 // the arms are an uninhabited type. Which is OK.
480484 hir:: MatchSource :: AwaitDesugar | hir:: MatchSource :: TryDesugar ( _) => { }
@@ -612,7 +616,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
612616 refutability : RefutableFlag ,
613617 scrut : Option < & Expr < ' tcx > > ,
614618 ) -> 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) ;
616621 let pat = self . lower_pattern ( & cx, pat) ?;
617622 let arms = [ MatchArm { pat, arm_data : self . lint_level , has_guard : false } ] ;
618623 let report = self . analyze_patterns ( & cx, & arms, pat. ty ( ) . inner ( ) ) ?;
@@ -626,7 +631,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
626631 ) -> Result < RefutableFlag , ErrorGuaranteed > {
627632 let ( cx, report) = self . analyze_binding ( pat, Refutable , scrut) ?;
628633 // 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 ) ;
630635 // If the list of witnesses is empty, the match is exhaustive, i.e. the `if let` pattern is
631636 // irrefutable.
632637 Ok ( if report. non_exhaustiveness_witnesses . is_empty ( ) { Irrefutable } else { Refutable } )
@@ -916,6 +921,7 @@ fn report_unreachable_pattern<'p, 'tcx>(
916921 hir_id : HirId ,
917922 pat : & DeconstructedPat < ' p , ' tcx > ,
918923 explanation : & RedundancyExplanation < ' p , ' tcx > ,
924+ suggest_remove : Option < Span > ,
919925) {
920926 let pat_span = pat. data ( ) . span ;
921927 let mut lint = UnreachablePattern {
@@ -924,6 +930,7 @@ fn report_unreachable_pattern<'p, 'tcx>(
924930 covered_by_catchall : None ,
925931 covered_by_one : None ,
926932 covered_by_many : None ,
933+ suggest_remove,
927934 } ;
928935 match explanation. covered_by . as_slice ( ) {
929936 [ ] => {
@@ -964,10 +971,28 @@ fn report_unreachable_pattern<'p, 'tcx>(
964971}
965972
966973/// 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 ( ) ;
968980 for ( arm, is_useful) in report. arm_usefulness . iter ( ) {
969981 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)
971996 }
972997 }
973998}
0 commit comments