diff options
| author | bors <bors@rust-lang.org> | 2024-09-14 07:04:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-09-14 07:04:57 +0000 |
| commit | f9567d0f2bc8f6f7f45c42d432a5dbbd161a6104 (patch) | |
| tree | f9fdc646af42889ab9d89f13694e1a6d96a21cdf /compiler/rustc_mir_build/src | |
| parent | 4a47e8e449da0d4b8252483ecb831c842ff59aa2 (diff) | |
| parent | 1f696384005c27c49ee0e31b1b9031d61b89be6b (diff) | |
| download | rust-f9567d0f2bc8f6f7f45c42d432a5dbbd161a6104.tar.gz rust-f9567d0f2bc8f6f7f45c42d432a5dbbd161a6104.zip | |
Auto merge of #128991 - Nadrieril:rustfix-unreachable-pattern, r=compiler-errors
Add a machine-applicable suggestion to "unreachable pattern"
Diffstat (limited to 'compiler/rustc_mir_build/src')
| -rw-r--r-- | compiler/rustc_mir_build/src/errors.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 35 |
2 files changed, 32 insertions, 5 deletions
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 7f9eefd1d52..411e9420914 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -598,6 +598,8 @@ pub(crate) struct UnreachablePattern<'tcx> { #[note(mir_build_unreachable_covered_by_many)] pub(crate) covered_by_many: Option<MultiSpan>, pub(crate) covered_by_many_n_more_count: usize, + #[suggestion(code = "", applicability = "machine-applicable")] + pub(crate) suggest_remove: Option<Span>, } #[derive(Diagnostic)] diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 4c066a68ef9..3fde6466d8c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -413,7 +413,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { // Emit lints in the order in which they occur in the file. redundant_subpats.sort_unstable_by_key(|(pat, _)| pat.data().span); for (pat, explanation) in redundant_subpats { - report_unreachable_pattern(cx, arm.arm_data, pat, &explanation) + report_unreachable_pattern(cx, arm.arm_data, pat, &explanation, None) } } } @@ -474,7 +474,11 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { hir::MatchSource::ForLoopDesugar | hir::MatchSource::Postfix | hir::MatchSource::Normal - | hir::MatchSource::FormatArgs => report_arm_reachability(&cx, &report), + | hir::MatchSource::FormatArgs => { + let is_match_arm = + matches!(source, hir::MatchSource::Postfix | hir::MatchSource::Normal); + report_arm_reachability(&cx, &report, is_match_arm); + } // Unreachable patterns in try and await expressions occur when one of // the arms are an uninhabited type. Which is OK. hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar(_) => {} @@ -626,7 +630,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> { ) -> Result<RefutableFlag, ErrorGuaranteed> { let (cx, report) = self.analyze_binding(pat, Refutable, scrut)?; // Report if the pattern is unreachable, which can only occur when the type is uninhabited. - report_arm_reachability(&cx, &report); + report_arm_reachability(&cx, &report, false); // If the list of witnesses is empty, the match is exhaustive, i.e. the `if let` pattern is // irrefutable. Ok(if report.non_exhaustiveness_witnesses.is_empty() { Irrefutable } else { Refutable }) @@ -916,6 +920,7 @@ fn report_unreachable_pattern<'p, 'tcx>( hir_id: HirId, pat: &DeconstructedPat<'p, 'tcx>, explanation: &RedundancyExplanation<'p, 'tcx>, + whole_arm_span: Option<Span>, ) { static CAP_COVERED_BY_MANY: usize = 4; let pat_span = pat.data().span; @@ -928,6 +933,7 @@ fn report_unreachable_pattern<'p, 'tcx>( covered_by_one: None, covered_by_many: None, covered_by_many_n_more_count: 0, + suggest_remove: None, }; match explanation.covered_by.as_slice() { [] => { @@ -935,6 +941,7 @@ fn report_unreachable_pattern<'p, 'tcx>( lint.span = None; // Don't label the pattern itself lint.uninhabited_note = Some(()); // Give a link about empty types lint.matches_no_values = Some(pat_span); + lint.suggest_remove = whole_arm_span; // Suggest to remove the match arm pat.walk(&mut |subpat| { let ty = **subpat.ty(); if cx.is_uninhabited(ty) { @@ -982,10 +989,28 @@ fn report_unreachable_pattern<'p, 'tcx>( } /// Report unreachable arms, if any. -fn report_arm_reachability<'p, 'tcx>(cx: &PatCtxt<'p, 'tcx>, report: &UsefulnessReport<'p, 'tcx>) { +fn report_arm_reachability<'p, 'tcx>( + cx: &PatCtxt<'p, 'tcx>, + report: &UsefulnessReport<'p, 'tcx>, + is_match_arm: bool, +) { + let sm = cx.tcx.sess.source_map(); for (arm, is_useful) in report.arm_usefulness.iter() { if let Usefulness::Redundant(explanation) = is_useful { - report_unreachable_pattern(cx, arm.arm_data, arm.pat, explanation) + let hir_id = arm.arm_data; + let arm_span = cx.tcx.hir().span(hir_id); + let whole_arm_span = if is_match_arm { + // If the arm is followed by a comma, extend the span to include it. + let with_whitespace = sm.span_extend_while_whitespace(arm_span); + if let Some(comma) = sm.span_look_ahead(with_whitespace, ",", Some(1)) { + Some(arm_span.to(comma)) + } else { + Some(arm_span) + } + } else { + None + }; + report_unreachable_pattern(cx, hir_id, arm.pat, explanation, whole_arm_span) } } } |
