mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 09:27:27 +00:00
Remove unneeded indirection on PatCtxt
This commit is contained in:
parent
26baab5d28
commit
f4a95c93fe
3 changed files with 24 additions and 24 deletions
|
@ -373,12 +373,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
|||
let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) =
|
||||
db.body_with_source_map(self.owner);
|
||||
|
||||
let match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() {
|
||||
let _match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() {
|
||||
return;
|
||||
} else {
|
||||
&infer.type_of_expr[match_expr]
|
||||
};
|
||||
// eprintln!("ExprValidator::validate_match2({:?})", match_expr_ty.kind(&Interner));
|
||||
// eprintln!("ExprValidator::validate_match2({:?})", _match_expr_ty.kind(&Interner));
|
||||
|
||||
let pattern_arena = usefulness::PatternArena::clone_from(&body.pats);
|
||||
let cx = usefulness::MatchCheckCtx {
|
||||
|
|
|
@ -143,7 +143,7 @@ impl Constructor {
|
|||
/// matrix, unless all of them are.
|
||||
pub(super) fn split<'a>(
|
||||
&self,
|
||||
pcx: &PatCtxt<'_>,
|
||||
pcx: PatCtxt<'_>,
|
||||
ctors: impl Iterator<Item = &'a Constructor> + Clone,
|
||||
) -> SmallVec<[Self; 1]> {
|
||||
match self {
|
||||
|
@ -166,7 +166,7 @@ impl Constructor {
|
|||
/// this checks for inclusion.
|
||||
// We inline because this has a single call site in `Matrix::specialize_constructor`.
|
||||
#[inline]
|
||||
pub(super) fn is_covered_by(&self, pcx: &PatCtxt<'_>, other: &Self) -> bool {
|
||||
pub(super) fn is_covered_by(&self, pcx: PatCtxt<'_>, other: &Self) -> bool {
|
||||
// This must be kept in sync with `is_covered_by_any`.
|
||||
match (self, other) {
|
||||
// Wildcards cover anything
|
||||
|
@ -188,7 +188,7 @@ impl Constructor {
|
|||
/// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is
|
||||
/// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is
|
||||
/// assumed to have been split from a wildcard.
|
||||
fn is_covered_by_any(&self, pcx: &PatCtxt<'_>, used_ctors: &[Constructor]) -> bool {
|
||||
fn is_covered_by_any(&self, pcx: PatCtxt<'_>, used_ctors: &[Constructor]) -> bool {
|
||||
if used_ctors.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ pub(super) struct SplitWildcard {
|
|||
}
|
||||
|
||||
impl SplitWildcard {
|
||||
pub(super) fn new(pcx: &PatCtxt<'_>) -> Self {
|
||||
pub(super) fn new(pcx: PatCtxt<'_>) -> Self {
|
||||
// let cx = pcx.cx;
|
||||
// let make_range = |start, end| IntRange(todo!());
|
||||
|
||||
|
@ -260,7 +260,7 @@ impl SplitWildcard {
|
|||
/// do what you want.
|
||||
pub(super) fn split<'a>(
|
||||
&mut self,
|
||||
pcx: &PatCtxt<'_>,
|
||||
pcx: PatCtxt<'_>,
|
||||
ctors: impl Iterator<Item = &'a Constructor> + Clone,
|
||||
) {
|
||||
// Since `all_ctors` never contains wildcards, this won't recurse further.
|
||||
|
@ -270,21 +270,21 @@ impl SplitWildcard {
|
|||
}
|
||||
|
||||
/// Whether there are any value constructors for this type that are not present in the matrix.
|
||||
fn any_missing(&self, pcx: &PatCtxt<'_>) -> bool {
|
||||
fn any_missing(&self, pcx: PatCtxt<'_>) -> bool {
|
||||
self.iter_missing(pcx).next().is_some()
|
||||
}
|
||||
|
||||
/// Iterate over the constructors for this type that are not present in the matrix.
|
||||
pub(super) fn iter_missing<'a>(
|
||||
&'a self,
|
||||
pcx: &'a PatCtxt<'_>,
|
||||
pcx: PatCtxt<'a>,
|
||||
) -> impl Iterator<Item = &'a Constructor> {
|
||||
self.all_ctors.iter().filter(move |ctor| !ctor.is_covered_by_any(pcx, &self.matrix_ctors))
|
||||
}
|
||||
|
||||
/// Return the set of constructors resulting from splitting the wildcard. As explained at the
|
||||
/// top of the file, if any constructors are missing we can ignore the present ones.
|
||||
fn into_ctors(self, pcx: &PatCtxt<'_>) -> SmallVec<[Constructor; 1]> {
|
||||
fn into_ctors(self, pcx: PatCtxt<'_>) -> SmallVec<[Constructor; 1]> {
|
||||
if self.any_missing(pcx) {
|
||||
// Some constructors are missing, thus we can specialize with the special `Missing`
|
||||
// constructor, which stands for those constructors that are not seen in the matrix,
|
||||
|
@ -313,7 +313,7 @@ impl SplitWildcard {
|
|||
//
|
||||
// The exception is: if we are at the top-level, for example in an empty match, we
|
||||
// sometimes prefer reporting the list of constructors instead of just `_`.
|
||||
let report_when_all_missing = pcx.is_top_level && !IntRange::is_integral(&pcx.ty);
|
||||
let report_when_all_missing = pcx.is_top_level && !IntRange::is_integral(pcx.ty);
|
||||
let ctor = if !self.matrix_ctors.is_empty() || report_when_all_missing {
|
||||
Missing
|
||||
} else {
|
||||
|
@ -381,8 +381,8 @@ impl Fields {
|
|||
Fields::Vec(pats)
|
||||
}
|
||||
|
||||
pub(crate) fn wildcards(pcx: &PatCtxt<'_>, constructor: &Constructor) -> Self {
|
||||
let ty = &pcx.ty;
|
||||
pub(crate) fn wildcards(pcx: PatCtxt<'_>, constructor: &Constructor) -> Self {
|
||||
let ty = pcx.ty;
|
||||
let cx = pcx.cx;
|
||||
let wildcard_from_ty = |ty| cx.alloc_pat(Pat::Wild, ty);
|
||||
|
||||
|
@ -446,7 +446,7 @@ impl Fields {
|
|||
/// `ty`: `Option<bool>`
|
||||
/// `self`: `[false]`
|
||||
/// returns `Some(false)`
|
||||
pub(super) fn apply(self, pcx: &PatCtxt<'_>, ctor: &Constructor) -> Pat {
|
||||
pub(super) fn apply(self, pcx: PatCtxt<'_>, ctor: &Constructor) -> Pat {
|
||||
let subpatterns_and_indices = self.patterns_and_indices();
|
||||
let mut subpatterns = subpatterns_and_indices.iter().map(|&(_, p)| p);
|
||||
|
||||
|
|
|
@ -51,11 +51,11 @@ impl<'a> MatchCheckCtx<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub(super) struct PatCtxt<'a> {
|
||||
pub(super) cx: &'a MatchCheckCtx<'a>,
|
||||
/// Type of the current column under investigation.
|
||||
pub(super) ty: Ty,
|
||||
pub(super) ty: &'a Ty,
|
||||
/// Whether the current pattern is the whole pattern as found in a match arm, or if it's a
|
||||
/// subpattern.
|
||||
pub(super) is_top_level: bool,
|
||||
|
@ -223,7 +223,7 @@ impl Matrix {
|
|||
/// This computes `S(constructor, self)`. See top of the file for explanations.
|
||||
fn specialize_constructor(
|
||||
&self,
|
||||
pcx: &PatCtxt<'_>,
|
||||
pcx: PatCtxt<'_>,
|
||||
ctor: &Constructor,
|
||||
ctor_wild_subpatterns: &Fields,
|
||||
) -> Matrix {
|
||||
|
@ -447,7 +447,7 @@ impl Usefulness {
|
|||
/// with the results of specializing with the other constructors.
|
||||
fn apply_constructor(
|
||||
self,
|
||||
pcx: &PatCtxt<'_>,
|
||||
pcx: PatCtxt<'_>,
|
||||
matrix: &Matrix,
|
||||
ctor: &Constructor,
|
||||
ctor_wild_subpatterns: &Fields,
|
||||
|
@ -555,7 +555,7 @@ impl Witness {
|
|||
/// pats: [(false, "foo"), 42] => X { a: (false, "foo"), b: 42 }
|
||||
fn apply_constructor(
|
||||
mut self,
|
||||
pcx: &PatCtxt<'_>,
|
||||
pcx: PatCtxt<'_>,
|
||||
ctor: &Constructor,
|
||||
ctor_wild_subpatterns: &Fields,
|
||||
) -> Self {
|
||||
|
@ -623,7 +623,7 @@ fn is_useful(
|
|||
// FIXME(Nadrieril): Hack to work around type normalization issues (see rust-lang/rust#72476).
|
||||
// TODO(iDawer): ty.strip_references() ?
|
||||
let ty = matrix.heads().next().map_or(cx.type_of(v.head()), |r| cx.type_of(r));
|
||||
let pcx = PatCtxt { cx, ty, is_top_level };
|
||||
let pcx = PatCtxt { cx, ty: &ty, is_top_level };
|
||||
|
||||
// If the first pattern is an or-pattern, expand it.
|
||||
let ret = if v.head().is_or_pat(cx) {
|
||||
|
@ -657,20 +657,20 @@ fn is_useful(
|
|||
// }
|
||||
|
||||
// We split the head constructor of `v`.
|
||||
let split_ctors = v_ctor.split(&pcx, matrix.head_ctors(cx));
|
||||
let split_ctors = v_ctor.split(pcx, matrix.head_ctors(cx));
|
||||
// For each constructor, we compute whether there's a value that starts with it that would
|
||||
// witness the usefulness of `v`.
|
||||
let start_matrix = matrix;
|
||||
let usefulnesses = split_ctors.into_iter().map(|ctor| {
|
||||
// debug!("specialize({:?})", ctor);
|
||||
// We cache the result of `Fields::wildcards` because it is used a lot.
|
||||
let ctor_wild_subpatterns = Fields::wildcards(&pcx, &ctor);
|
||||
let ctor_wild_subpatterns = Fields::wildcards(pcx, &ctor);
|
||||
let spec_matrix =
|
||||
start_matrix.specialize_constructor(&pcx, &ctor, &ctor_wild_subpatterns);
|
||||
start_matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns);
|
||||
let v = v.pop_head_constructor(&ctor_wild_subpatterns, cx);
|
||||
let usefulness =
|
||||
is_useful(cx, &spec_matrix, &v, witness_preference, is_under_guard, false);
|
||||
usefulness.apply_constructor(&pcx, start_matrix, &ctor, &ctor_wild_subpatterns)
|
||||
usefulness.apply_constructor(pcx, start_matrix, &ctor, &ctor_wild_subpatterns)
|
||||
});
|
||||
Usefulness::merge(witness_preference, usefulnesses)
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue