Skip to content

Commit 76dea86

Browse files
committed
Factor out a struct that holds subfields of a pattern
1 parent 160eebe commit 76dea86

File tree

1 file changed

+43
-10
lines changed

1 file changed

+43
-10
lines changed

src/librustc_mir_build/hair/pattern/_match.rs

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
441441
&self,
442442
cx: &mut MatchCheckCtxt<'p, 'tcx>,
443443
constructor: &Constructor<'tcx>,
444-
ctor_wild_subpatterns: &'p [Pat<'tcx>],
444+
ctor_wild_subpatterns: &Fields<'p, 'tcx>,
445445
) -> Option<PatStack<'p, 'tcx>> {
446446
let new_heads = specialize_one_pattern(cx, self.head(), constructor, ctor_wild_subpatterns);
447447
new_heads.map(|mut new_head| {
@@ -503,7 +503,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
503503
&self,
504504
cx: &mut MatchCheckCtxt<'p, 'tcx>,
505505
constructor: &Constructor<'tcx>,
506-
ctor_wild_subpatterns: &'p [Pat<'tcx>],
506+
ctor_wild_subpatterns: &Fields<'p, 'tcx>,
507507
) -> Matrix<'p, 'tcx> {
508508
self.0
509509
.iter()
@@ -722,10 +722,12 @@ impl Slice {
722722
}
723723
}
724724

725+
/// A value can be decomposed into a constructor applied to some fields. This struct represents
726+
/// the constructor. See also `Fields`.
725727
#[derive(Clone, Debug, PartialEq)]
726728
enum Constructor<'tcx> {
727-
/// The constructor of all patterns that don't vary by constructor,
728-
/// e.g., struct patterns and fixed-length arrays.
729+
/// The constructor for patterns that have a single constructor, like tuples, struct patterns
730+
/// and fixed-length arrays.
729731
Single,
730732
/// Enum variants.
731733
Variant(DefId),
@@ -1027,6 +1029,38 @@ impl<'tcx> Constructor<'tcx> {
10271029
}
10281030
}
10291031

1032+
/// A value can be decomposed into a constructor applied to some fields. This struct represents
1033+
/// those fields, generalized to allow patterns in each field. See also `Constructor`.
1034+
#[derive(Debug, Clone)]
1035+
enum Fields<'p, 'tcx> {
1036+
Slice(&'p [Pat<'tcx>]),
1037+
}
1038+
1039+
impl<'p, 'tcx> Fields<'p, 'tcx> {
1040+
/// Creates a new list of wildcard fields for a given constructor.
1041+
fn wildcards(
1042+
cx: &MatchCheckCtxt<'p, 'tcx>,
1043+
constructor: &Constructor<'tcx>,
1044+
ty: Ty<'tcx>,
1045+
) -> Self {
1046+
debug!("Fields::wildcards({:#?}, {:?})", constructor, ty);
1047+
let pats = cx.pattern_arena.alloc_from_iter(constructor.wildcard_subpatterns(cx, ty));
1048+
Fields::Slice(pats)
1049+
}
1050+
1051+
fn len(&self) -> usize {
1052+
match self {
1053+
Fields::Slice(pats) => pats.len(),
1054+
}
1055+
}
1056+
1057+
fn iter<'a>(&'a self) -> impl Iterator<Item = &'p Pat<'tcx>> + Captures<'a> {
1058+
match self {
1059+
Fields::Slice(pats) => pats.iter(),
1060+
}
1061+
}
1062+
}
1063+
10301064
#[derive(Clone, Debug)]
10311065
crate enum Usefulness<'tcx, 'p> {
10321066
/// Carries a list of unreachable subpatterns. Used only in the presence of or-patterns.
@@ -1823,10 +1857,9 @@ fn is_useful_specialized<'p, 'tcx>(
18231857
) -> Usefulness<'tcx, 'p> {
18241858
debug!("is_useful_specialized({:#?}, {:#?}, {:?})", v, ctor, lty);
18251859

1826-
let ctor_wild_subpatterns =
1827-
cx.pattern_arena.alloc_from_iter(ctor.wildcard_subpatterns(cx, lty));
1828-
let matrix = matrix.specialize_constructor(cx, &ctor, ctor_wild_subpatterns);
1829-
v.specialize_constructor(cx, &ctor, ctor_wild_subpatterns)
1860+
let ctor_wild_subpatterns = Fields::wildcards(cx, &ctor, lty);
1861+
let matrix = matrix.specialize_constructor(cx, &ctor, &ctor_wild_subpatterns);
1862+
v.specialize_constructor(cx, &ctor, &ctor_wild_subpatterns)
18301863
.map(|v| is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false))
18311864
.map(|u| u.apply_constructor(cx, &ctor, lty))
18321865
.unwrap_or(NotUseful)
@@ -2295,7 +2328,7 @@ fn constructor_covered_by_range<'tcx>(
22952328
fn patterns_for_variant<'p, 'tcx>(
22962329
cx: &mut MatchCheckCtxt<'p, 'tcx>,
22972330
subpatterns: &'p [FieldPat<'tcx>],
2298-
ctor_wild_subpatterns: &'p [Pat<'tcx>],
2331+
ctor_wild_subpatterns: &Fields<'p, 'tcx>,
22992332
is_non_exhaustive: bool,
23002333
) -> PatStack<'p, 'tcx> {
23012334
let mut result: SmallVec<_> = ctor_wild_subpatterns.iter().collect();
@@ -2326,7 +2359,7 @@ fn specialize_one_pattern<'p, 'tcx>(
23262359
cx: &mut MatchCheckCtxt<'p, 'tcx>,
23272360
pat: &'p Pat<'tcx>,
23282361
constructor: &Constructor<'tcx>,
2329-
ctor_wild_subpatterns: &'p [Pat<'tcx>],
2362+
ctor_wild_subpatterns: &Fields<'p, 'tcx>,
23302363
) -> Option<PatStack<'p, 'tcx>> {
23312364
if let NonExhaustive = constructor {
23322365
// Only a wildcard pattern can match the special extra constructor

0 commit comments

Comments
 (0)