Remove unneeded indirection on PatCtxt

This commit is contained in:
Dawer 2021-04-29 10:04:24 +05:00
parent 26baab5d28
commit f4a95c93fe
3 changed files with 24 additions and 24 deletions

View file

@ -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 {

View file

@ -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);

View file

@ -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)
};