Skip to content

Commit 175976e

Browse files
committed
Refactor "wild constructor" construction
1 parent b454581 commit 175976e

File tree

1 file changed

+33
-40
lines changed

1 file changed

+33
-40
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -642,15 +642,17 @@ impl<'tcx> Constructor<'tcx> {
642642
}
643643
}
644644

645+
/// This returns one wildcard pattern for each argument to this constructor.
645646
fn wildcard_subpatterns<'a>(
646647
&self,
647648
cx: &MatchCheckCtxt<'a, 'tcx>,
648649
ty: Ty<'tcx>,
649-
) -> Vec<Pat<'tcx>> {
650-
constructor_sub_pattern_tys(cx, self, ty)
651-
.into_iter()
652-
.map(|ty| Pat { ty, span: DUMMY_SP, kind: box PatKind::Wild })
653-
.collect()
650+
) -> impl Iterator<Item = Pat<'tcx>> + DoubleEndedIterator {
651+
constructor_sub_pattern_tys(cx, self, ty).into_iter().map(|ty| Pat {
652+
ty,
653+
span: DUMMY_SP,
654+
kind: box PatKind::Wild,
655+
})
654656
}
655657

656658
/// This computes the arity of a constructor. The arity of a constructor
@@ -735,6 +737,12 @@ impl<'tcx> Constructor<'tcx> {
735737

736738
Pat { ty, span: DUMMY_SP, kind: Box::new(pat) }
737739
}
740+
741+
/// Like `apply`, but where all the subpatterns are wildcards `_`.
742+
fn apply_wildcards<'a>(&self, cx: &MatchCheckCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> {
743+
let pats = self.wildcard_subpatterns(cx, ty).rev();
744+
self.apply(cx, ty, pats)
745+
}
738746
}
739747

740748
#[derive(Clone, Debug)]
@@ -807,16 +815,6 @@ impl<'tcx> Witness<'tcx> {
807815
self.0.into_iter().next().unwrap()
808816
}
809817

810-
fn push_wild_constructor<'a>(
811-
mut self,
812-
cx: &MatchCheckCtxt<'a, 'tcx>,
813-
ctor: &Constructor<'tcx>,
814-
ty: Ty<'tcx>,
815-
) -> Self {
816-
self.0.extend(ctor.wildcard_subpatterns(cx, ty));
817-
self.apply_constructor(cx, ctor, ty)
818-
}
819-
820818
/// Constructs a partial witness for a pattern given a list of
821819
/// patterns expanded by the specialization step.
822820
///
@@ -1530,33 +1528,28 @@ pub fn is_useful<'p, 'a, 'tcx>(
15301528
// `(<direction-1>, <direction-2>, true)` - we are
15311529
// satisfied with `(_, _, true)`. In this case,
15321530
// `used_ctors` is empty.
1533-
let new_witnesses = if is_non_exhaustive || used_ctors.is_empty() {
1534-
// All constructors are unused. Add wild patterns
1531+
let new_patterns = if is_non_exhaustive || used_ctors.is_empty() {
1532+
// All constructors are unused. Add a wild pattern
15351533
// rather than each individual constructor.
1536-
pats.into_iter()
1537-
.map(|mut witness| {
1538-
witness.0.push(Pat {
1539-
ty: pcx.ty,
1540-
span: DUMMY_SP,
1541-
kind: box PatKind::Wild,
1542-
});
1543-
witness
1544-
})
1545-
.collect()
1534+
vec![Pat { ty: pcx.ty, span: DUMMY_SP, kind: box PatKind::Wild }]
15461535
} else {
1547-
let missing_ctors: Vec<_> = missing_ctors.collect();
1548-
pats.into_iter()
1549-
.flat_map(|witness| {
1550-
missing_ctors.iter().map(move |ctor| {
1551-
// Extends the witness with a "wild" version of this
1552-
// constructor, that matches everything that can be built with
1553-
// it. For example, if `ctor` is a `Constructor::Variant` for
1554-
// `Option::Some`, this pushes the witness for `Some(_)`.
1555-
witness.clone().push_wild_constructor(cx, ctor, pcx.ty)
1556-
})
1557-
})
1558-
.collect()
1536+
// Construct for each missing constructor a "wild" version of this
1537+
// constructor, that matches everything that can be built with
1538+
// it. For example, if `ctor` is a `Constructor::Variant` for
1539+
// `Option::Some`, we get the pattern `Some(_)`.
1540+
missing_ctors.map(|ctor| ctor.apply_wildcards(cx, pcx.ty)).collect()
15591541
};
1542+
// Add the new patterns to each witness
1543+
let new_witnesses = pats
1544+
.into_iter()
1545+
.flat_map(|witness| {
1546+
new_patterns.iter().map(move |pat| {
1547+
let mut witness = witness.clone();
1548+
witness.0.push(pat.clone());
1549+
witness
1550+
})
1551+
})
1552+
.collect();
15601553
UsefulWithWitness(new_witnesses)
15611554
}
15621555
result => result,
@@ -1578,7 +1571,7 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
15781571
) -> Usefulness<'tcx> {
15791572
debug!("is_useful_specialized({:#?}, {:#?}, {:?})", v, ctor, lty);
15801573

1581-
let wild_patterns_owned = ctor.wildcard_subpatterns(cx, lty);
1574+
let wild_patterns_owned: Vec<_> = ctor.wildcard_subpatterns(cx, lty).collect();
15821575
let wild_patterns: Vec<_> = wild_patterns_owned.iter().collect();
15831576
let matrix = matrix.specialize_constructor(cx, &ctor, &wild_patterns);
15841577
match v.specialize_constructor(cx, &ctor, &wild_patterns) {

0 commit comments

Comments
 (0)