Replace local copy of exhaustiveness checking with upstream librarified version

This commit is contained in:
Nadrieril 2024-01-17 00:28:05 +01:00
parent d410d4a2ba
commit 2370b70f25
11 changed files with 603 additions and 1952 deletions

View file

@ -11,6 +11,7 @@ use hir_def::{ItemContainerId, Lookup};
use hir_expand::name;
use itertools::Itertools;
use rustc_hash::FxHashSet;
use rustc_pattern_analysis::usefulness::{compute_match_usefulness, ValidityConstraint};
use triomphe::Arc;
use typed_arena::Arena;
@ -18,8 +19,7 @@ use crate::{
db::HirDatabase,
diagnostics::match_check::{
self,
deconstruct_pat::DeconstructedPat,
usefulness::{compute_match_usefulness, MatchCheckCtx},
pat_analysis::{self, DeconstructedPat, MatchCheckCtx, WitnessPat},
},
display::HirDisplay,
InferenceResult, Ty, TyExt,
@ -152,7 +152,14 @@ impl ExprValidator {
}
let pattern_arena = Arena::new();
let cx = MatchCheckCtx::new(self.owner.module(db.upcast()), self.owner, db, &pattern_arena);
let ty_arena = Arena::new();
let cx = MatchCheckCtx::new(
self.owner.module(db.upcast()),
self.owner,
db,
&pattern_arena,
&ty_arena,
);
let mut m_arms = Vec::with_capacity(arms.len());
let mut has_lowering_errors = false;
@ -178,9 +185,10 @@ impl ExprValidator {
// If we had a NotUsefulMatchArm diagnostic, we could
// check the usefulness of each pattern as we added it
// to the matrix here.
let m_arm = match_check::MatchArm {
let m_arm = pat_analysis::MatchArm {
pat: self.lower_pattern(&cx, arm.pat, db, &body, &mut has_lowering_errors),
has_guard: arm.guard.is_some(),
arm_data: (),
};
m_arms.push(m_arm);
if !has_lowering_errors {
@ -197,7 +205,15 @@ impl ExprValidator {
return;
}
let report = compute_match_usefulness(&cx, &m_arms, scrut_ty);
let report = match compute_match_usefulness(
rustc_pattern_analysis::MatchCtxt { tycx: &cx },
m_arms.as_slice(),
scrut_ty.clone(),
ValidityConstraint::ValidOnly,
) {
Ok(report) => report,
Err(void) => match void {},
};
// FIXME Report unreachable arms
// https://github.com/rust-lang/rust/blob/f31622a50/compiler/rustc_mir_build/src/thir/pattern/check_match.rs#L200
@ -213,7 +229,7 @@ impl ExprValidator {
fn lower_pattern<'p>(
&self,
cx: &MatchCheckCtx<'_, 'p>,
cx: &MatchCheckCtx<'p>,
pat: PatId,
db: &dyn HirDatabase,
body: &Body,
@ -221,7 +237,7 @@ impl ExprValidator {
) -> &'p DeconstructedPat<'p> {
let mut patcx = match_check::PatCtxt::new(db, &self.infer, body);
let pattern = patcx.lower_pattern(pat);
let pattern = cx.pattern_arena.alloc(DeconstructedPat::from_pat(cx, &pattern));
let pattern = cx.pattern_arena.alloc(cx.lower_pat(&pattern));
if !patcx.errors.is_empty() {
*have_errors = true;
}
@ -364,16 +380,16 @@ fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResul
}
fn missing_match_arms<'p>(
cx: &MatchCheckCtx<'_, 'p>,
cx: &MatchCheckCtx<'p>,
scrut_ty: &Ty,
witnesses: Vec<DeconstructedPat<'p>>,
witnesses: Vec<WitnessPat<'p>>,
arms: &[MatchArm],
) -> String {
struct DisplayWitness<'a, 'p>(&'a DeconstructedPat<'p>, &'a MatchCheckCtx<'a, 'p>);
struct DisplayWitness<'a, 'p>(&'a WitnessPat<'p>, &'a MatchCheckCtx<'p>);
impl fmt::Display for DisplayWitness<'_, '_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let DisplayWitness(witness, cx) = *self;
let pat = witness.to_pat(cx);
let pat = cx.hoist_witness_pat(witness);
write!(f, "{}", pat.display(cx.db))
}
}