diff options
| author | bors <bors@rust-lang.org> | 2024-07-26 10:51:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-26 10:51:04 +0000 |
| commit | 355efacf0d430331c962a38af39049b76bb6266b (patch) | |
| tree | 93b3896181a79c48fa9b48229e9f91d6306fbbb3 /compiler/rustc_pattern_analysis/src/rustc.rs | |
| parent | 83d67685acb520fe68d5d5adde4b25fb725490de (diff) | |
| parent | 940769a79b3c71915533d6eddc001a9b71bf5402 (diff) | |
| download | rust-355efacf0d430331c962a38af39049b76bb6266b.tar.gz rust-355efacf0d430331c962a38af39049b76bb6266b.zip | |
Auto merge of #128034 - Nadrieril:explain-unreachable, r=compiler-errors
exhaustiveness: Explain why a given pattern is considered unreachable This PR tells the user why a given pattern is considered unreachable. I reused the intersection information we were already computing; even though it's incomplete I convinced myself that it is sufficient to always get a set of patterns that cover the unreachable one. I'm not a fan of the diagnostic messages I came up with, I'm open to suggestions. Fixes https://github.com/rust-lang/rust/issues/127870. This is also the other one of the two diagnostic improvements I wanted to do before https://github.com/rust-lang/rust/pull/122792. Note: the first commit is an unrelated drive-by tweak. r? `@compiler-errors`
Diffstat (limited to 'compiler/rustc_pattern_analysis/src/rustc.rs')
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/rustc.rs | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 6ef2d69273e..910dd4c6c1a 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -20,6 +20,9 @@ use rustc_target::abi::{FieldIdx, Integer, VariantIdx, FIRST_VARIANT}; use crate::constructor::{ IntRange, MaybeInfiniteInt, OpaqueId, RangeEnd, Slice, SliceKind, VariantVisibility, }; +use crate::lints::lint_nonexhaustive_missing_variants; +use crate::pat_column::PatternColumn; +use crate::usefulness::{compute_match_usefulness, PlaceValidity}; use crate::{errors, Captures, PatCx, PrivateUninhabitedField}; use crate::constructor::Constructor::*; @@ -29,6 +32,8 @@ pub type Constructor<'p, 'tcx> = crate::constructor::Constructor<RustcPatCtxt<'p pub type ConstructorSet<'p, 'tcx> = crate::constructor::ConstructorSet<RustcPatCtxt<'p, 'tcx>>; pub type DeconstructedPat<'p, 'tcx> = crate::pat::DeconstructedPat<RustcPatCtxt<'p, 'tcx>>; pub type MatchArm<'p, 'tcx> = crate::MatchArm<'p, RustcPatCtxt<'p, 'tcx>>; +pub type RedundancyExplanation<'p, 'tcx> = + crate::usefulness::RedundancyExplanation<'p, RustcPatCtxt<'p, 'tcx>>; pub type Usefulness<'p, 'tcx> = crate::usefulness::Usefulness<'p, RustcPatCtxt<'p, 'tcx>>; pub type UsefulnessReport<'p, 'tcx> = crate::usefulness::UsefulnessReport<'p, RustcPatCtxt<'p, 'tcx>>; @@ -1058,3 +1063,26 @@ fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> { expand(pat, &mut pats); pats } + +/// The entrypoint for this crate. Computes whether a match is exhaustive and which of its arms are +/// useful, and runs some lints. +pub fn analyze_match<'p, 'tcx>( + tycx: &RustcPatCtxt<'p, 'tcx>, + arms: &[MatchArm<'p, 'tcx>], + scrut_ty: Ty<'tcx>, + pattern_complexity_limit: Option<usize>, +) -> Result<UsefulnessReport<'p, 'tcx>, ErrorGuaranteed> { + let scrut_ty = tycx.reveal_opaque_ty(scrut_ty); + let scrut_validity = PlaceValidity::from_bool(tycx.known_valid_scrutinee); + let report = + compute_match_usefulness(tycx, arms, scrut_ty, scrut_validity, pattern_complexity_limit)?; + + // Run the non_exhaustive_omitted_patterns lint. Only run on refutable patterns to avoid hitting + // `if let`s. Only run if the match is exhaustive otherwise the error is redundant. + if tycx.refutable && report.non_exhaustiveness_witnesses.is_empty() { + let pat_column = PatternColumn::new(arms); + lint_nonexhaustive_missing_variants(tycx, arms, &pat_column, scrut_ty)?; + } + + Ok(report) +} |
