diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 4d17e8c9a1b..88018b5d9a2 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs @@ -373,12 +373,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> { let (body, source_map): (Arc, Arc) = 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 { diff --git a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs index 2f35552055f..d41b95d2f96 100644 --- a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs +++ b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs @@ -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 + 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 + 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 { 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` /// `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); diff --git a/crates/hir_ty/src/diagnostics/pattern/usefulness.rs b/crates/hir_ty/src/diagnostics/pattern/usefulness.rs index 89e6c659328..7d9ab849b14 100644 --- a/crates/hir_ty/src/diagnostics/pattern/usefulness.rs +++ b/crates/hir_ty/src/diagnostics/pattern/usefulness.rs @@ -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) };