Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 43d445c

Browse files
committed
Pass Matrix explicitly instead of via PatCtxt
1 parent 8b38b68 commit 43d445c

File tree

2 files changed

+48
-27
lines changed

2 files changed

+48
-27
lines changed

compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_middle::mir::Field;
1919
use rustc_middle::ty::layout::IntegerExt;
2020
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
2121
use rustc_session::lint;
22-
use rustc_span::DUMMY_SP;
22+
use rustc_span::{Span, DUMMY_SP};
2323
use rustc_target::abi::{Integer, Size, VariantIdx};
2424

2525
use smallvec::{smallvec, SmallVec};
@@ -184,12 +184,18 @@ impl IntRange {
184184
}
185185

186186
/// Lint on likely incorrect range patterns (#63987)
187-
pub(super) fn lint_overlapping_range_endpoints(&self, pcx: PatCtxt<'_, '_, '_>, hir_id: HirId) {
187+
pub(super) fn lint_overlapping_range_endpoints<'a, 'tcx: 'a>(
188+
&self,
189+
pcx: PatCtxt<'_, '_, 'tcx>,
190+
ctors: impl Iterator<Item = (&'a Constructor<'tcx>, Span)>,
191+
column_count: usize,
192+
hir_id: HirId,
193+
) {
188194
if self.is_singleton() {
189195
return;
190196
}
191197

192-
if pcx.matrix.column_count().unwrap_or(0) != 1 {
198+
if column_count != 1 {
193199
// FIXME: for now, only check for overlapping ranges on simple range
194200
// patterns. Otherwise with the current logic the following is detected
195201
// as overlapping:
@@ -203,9 +209,7 @@ impl IntRange {
203209
return;
204210
}
205211

206-
let overlaps: Vec<_> = pcx
207-
.matrix
208-
.head_ctors_and_spans(pcx.cx)
212+
let overlaps: Vec<_> = ctors
209213
.filter_map(|(ctor, span)| Some((ctor.as_int_range()?, span)))
210214
.filter(|(range, _)| self.suspicious_intersection(range))
211215
.map(|(range, span)| (self.intersection(&range).unwrap(), span))
@@ -655,28 +659,33 @@ impl<'tcx> Constructor<'tcx> {
655659
/// This function may discard some irrelevant constructors if this preserves behavior and
656660
/// diagnostics. Eg. for the `_` case, we ignore the constructors already present in the
657661
/// matrix, unless all of them are.
658-
pub(super) fn split<'p>(&self, pcx: PatCtxt<'_, 'p, 'tcx>) -> SmallVec<[Self; 1]> {
659-
debug!("Constructor::split({:#?}, {:#?})", self, pcx.matrix);
662+
pub(super) fn split<'a>(
663+
&self,
664+
pcx: PatCtxt<'_, '_, 'tcx>,
665+
ctors: impl Iterator<Item = &'a Constructor<'tcx>> + Clone,
666+
) -> SmallVec<[Self; 1]>
667+
where
668+
'tcx: 'a,
669+
{
670+
debug!("Constructor::split({:#?})", self);
660671

661672
match self {
662673
Wildcard => {
663674
let mut split_wildcard = SplitWildcard::new(pcx);
664-
split_wildcard.split(pcx);
675+
split_wildcard.split(pcx, ctors);
665676
split_wildcard.into_ctors(pcx)
666677
}
667678
// Fast-track if the range is trivial. In particular, we don't do the overlapping
668679
// ranges check.
669680
IntRange(ctor_range) if !ctor_range.is_singleton() => {
670681
let mut split_range = SplitIntRange::new(ctor_range.clone());
671-
let intranges =
672-
pcx.matrix.head_ctors(pcx.cx).filter_map(|ctor| ctor.as_int_range());
682+
let intranges = ctors.filter_map(|ctor| ctor.as_int_range());
673683
split_range.split(intranges.cloned());
674684
split_range.iter().map(IntRange).collect()
675685
}
676686
&Slice(Slice { kind: VarLen(self_prefix, self_suffix), array_len }) => {
677687
let mut split_self = SplitVarLenSlice::new(self_prefix, self_suffix, array_len);
678-
let slices =
679-
pcx.matrix.head_ctors(pcx.cx).filter_map(|c| c.as_slice()).map(|s| s.kind);
688+
let slices = ctors.filter_map(|c| c.as_slice()).map(|s| s.kind);
680689
split_self.split(slices);
681690
split_self.iter().map(Slice).collect()
682691
}
@@ -912,11 +921,17 @@ impl<'tcx> SplitWildcard<'tcx> {
912921

913922
/// Pass a set of constructors relative to which to split this one. Don't call twice, it won't
914923
/// do what you want.
915-
pub(super) fn split(&mut self, pcx: PatCtxt<'_, '_, 'tcx>) {
916-
self.matrix_ctors =
917-
pcx.matrix.head_ctors(pcx.cx).cloned().filter(|c| !c.is_wildcard()).collect();
924+
pub(super) fn split<'a>(
925+
&mut self,
926+
pcx: PatCtxt<'_, '_, 'tcx>,
927+
ctors: impl Iterator<Item = &'a Constructor<'tcx>> + Clone,
928+
) where
929+
'tcx: 'a,
930+
{
918931
// Since `all_ctors` never contains wildcards, this won't recurse further.
919-
self.all_ctors = self.all_ctors.iter().flat_map(|ctor| ctor.split(pcx)).collect();
932+
self.all_ctors =
933+
self.all_ctors.iter().flat_map(|ctor| ctor.split(pcx, ctors.clone())).collect();
934+
self.matrix_ctors = ctors.filter(|c| !c.is_wildcard()).cloned().collect();
920935
}
921936

922937
/// Whether there are any value constructors for this type that are not present in the matrix.

compiler/rustc_mir_build/src/thir/pattern/usefulness.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,6 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
358358
#[derive(Copy, Clone)]
359359
pub(super) struct PatCtxt<'a, 'p, 'tcx> {
360360
pub(super) cx: &'a MatchCheckCtxt<'p, 'tcx>,
361-
/// Current state of the matrix.
362-
pub(super) matrix: &'a Matrix<'p, 'tcx>,
363361
/// Type of the current column under investigation.
364362
pub(super) ty: Ty<'tcx>,
365363
/// Span of the current pattern under investigation.
@@ -538,7 +536,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
538536
pub(super) fn head_ctors<'a>(
539537
&'a self,
540538
cx: &'a MatchCheckCtxt<'p, 'tcx>,
541-
) -> impl Iterator<Item = &'a Constructor<'tcx>> + Captures<'p> {
539+
) -> impl Iterator<Item = &'a Constructor<'tcx>> + Captures<'p> + Clone {
542540
self.patterns.iter().map(move |r| r.head_ctor(cx))
543541
}
544542

@@ -804,14 +802,15 @@ impl<'tcx> Usefulness<'tcx> {
804802
fn apply_constructor<'p>(
805803
self,
806804
pcx: PatCtxt<'_, 'p, 'tcx>,
805+
matrix: &Matrix<'p, 'tcx>, // used to compute missing ctors
807806
ctor: &Constructor<'tcx>,
808807
ctor_wild_subpatterns: &Fields<'p, 'tcx>,
809808
) -> Self {
810809
match self {
811810
UsefulWithWitness(witnesses) => {
812811
let new_witnesses = if ctor.is_wildcard() {
813812
let mut split_wildcard = SplitWildcard::new(pcx);
814-
split_wildcard.split(pcx);
813+
split_wildcard.split(pcx, matrix.head_ctors(pcx.cx));
815814
let new_patterns = split_wildcard.report_missing_patterns(pcx);
816815
witnesses
817816
.into_iter()
@@ -968,7 +967,7 @@ fn is_useful<'p, 'tcx>(
968967

969968
// FIXME(Nadrieril): Hack to work around type normalization issues (see #72476).
970969
let ty = matrix.heads().next().map(|r| r.ty).unwrap_or(v.head().ty);
971-
let pcx = PatCtxt { cx, matrix, ty, span: v.head().span, is_top_level };
970+
let pcx = PatCtxt { cx, ty, span: v.head().span, is_top_level };
972971

973972
debug!("is_useful_expand_first_col: ty={:#?}, expanding {:#?}", pcx.ty, v.head());
974973

@@ -995,20 +994,27 @@ fn is_useful<'p, 'tcx>(
995994
let v_ctor = v.head_ctor(cx);
996995
if let Constructor::IntRange(ctor_range) = &v_ctor {
997996
// Lint on likely incorrect range patterns (#63987)
998-
ctor_range.lint_overlapping_range_endpoints(pcx, hir_id)
997+
ctor_range.lint_overlapping_range_endpoints(
998+
pcx,
999+
matrix.head_ctors_and_spans(cx),
1000+
matrix.column_count().unwrap_or(0),
1001+
hir_id,
1002+
)
9991003
}
10001004
// We split the head constructor of `v`.
1001-
let split_ctors = v_ctor.split(pcx);
1005+
let split_ctors = v_ctor.split(pcx, matrix.head_ctors(cx));
10021006
// For each constructor, we compute whether there's a value that starts with it that would
10031007
// witness the usefulness of `v`.
1008+
let start_matrix = &matrix;
10041009
let usefulnesses = split_ctors.into_iter().map(|ctor| {
10051010
// We cache the result of `Fields::wildcards` because it is used a lot.
10061011
let ctor_wild_subpatterns = Fields::wildcards(pcx, &ctor);
1007-
let matrix = pcx.matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns);
1012+
let spec_matrix =
1013+
start_matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns);
10081014
let v = v.pop_head_constructor(&ctor_wild_subpatterns);
10091015
let usefulness =
1010-
is_useful(pcx.cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false);
1011-
usefulness.apply_constructor(pcx, &ctor, &ctor_wild_subpatterns)
1016+
is_useful(cx, &spec_matrix, &v, witness_preference, hir_id, is_under_guard, false);
1017+
usefulness.apply_constructor(pcx, start_matrix, &ctor, &ctor_wild_subpatterns)
10121018
});
10131019
Usefulness::merge(usefulnesses)
10141020
};

0 commit comments

Comments
 (0)