Skip to content

Commit 23ca38e

Browse files
committed
Factor out some pattern-stack related functions
1 parent 403d6bd commit 23ca38e

File tree

1 file changed

+52
-12
lines changed

1 file changed

+52
-12
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,25 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
379379
fn iter(&self) -> impl Iterator<Item = &Pat<'tcx>> {
380380
self.0.iter().map(|p| *p)
381381
}
382+
383+
/// This computes `D(self)`. See top of the file for explanations.
384+
fn specialize_wildcard(&self) -> Option<Self> {
385+
if self.head().is_wildcard() { Some(self.to_tail()) } else { None }
386+
}
387+
388+
/// This computes `S(constructor, self)`. See top of the file for explanations.
389+
fn specialize_constructor<'a, 'q>(
390+
&self,
391+
cx: &mut MatchCheckCtxt<'a, 'tcx>,
392+
constructor: &Constructor<'tcx>,
393+
wild_patterns: &[&'q Pat<'tcx>],
394+
) -> Option<PatStack<'q, 'tcx>>
395+
where
396+
'a: 'q,
397+
'p: 'q,
398+
{
399+
specialize(cx, self, constructor, wild_patterns)
400+
}
382401
}
383402

384403
impl<'p, 'tcx> Default for PatStack<'p, 'tcx> {
@@ -407,6 +426,30 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
407426
pub fn push(&mut self, row: PatStack<'p, 'tcx>) {
408427
self.0.push(row)
409428
}
429+
430+
/// This computes `D(self)`. See top of the file for explanations.
431+
fn specialize_wildcard(&self) -> Self {
432+
self.0.iter().filter_map(|r| r.specialize_wildcard()).collect()
433+
}
434+
435+
/// This computes `S(constructor, self)`. See top of the file for explanations.
436+
fn specialize_constructor<'a, 'q>(
437+
&self,
438+
cx: &mut MatchCheckCtxt<'a, 'tcx>,
439+
constructor: &Constructor<'tcx>,
440+
wild_patterns: &[&'q Pat<'tcx>],
441+
) -> Matrix<'q, 'tcx>
442+
where
443+
'a: 'q,
444+
'p: 'q,
445+
{
446+
Matrix(
447+
self.0
448+
.iter()
449+
.filter_map(|r| r.specialize_constructor(cx, constructor, wild_patterns))
450+
.collect(),
451+
)
452+
}
410453
}
411454

412455
/// Pretty-printer for matrices of patterns, example:
@@ -1423,11 +1466,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
14231466
.find(|result| result.is_useful())
14241467
.unwrap_or(NotUseful)
14251468
} else {
1426-
let matrix = rows
1427-
.iter()
1428-
.filter_map(|r| if r.head().is_wildcard() { Some(r.to_tail()) } else { None })
1429-
.collect();
1430-
match is_useful(cx, &matrix, &v.to_tail(), witness, hir_id) {
1469+
let matrix = matrix.specialize_wildcard();
1470+
let v = v.to_tail();
1471+
match is_useful(cx, &matrix, &v, witness, hir_id) {
14311472
UsefulWithWitness(pats) => {
14321473
let cx = &*cx;
14331474
// In this case, there's at least one "free"
@@ -1523,7 +1564,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
15231564
/// to the specialised version of both the pattern matrix `P` and the new pattern `q`.
15241565
fn is_useful_specialized<'p, 'a, 'tcx>(
15251566
cx: &mut MatchCheckCtxt<'a, 'tcx>,
1526-
&Matrix(ref m): &Matrix<'p, 'tcx>,
1567+
matrix: &Matrix<'p, 'tcx>,
15271568
v: &PatStack<'_, 'tcx>,
15281569
ctor: Constructor<'tcx>,
15291570
lty: Ty<'tcx>,
@@ -1535,9 +1576,8 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
15351576
let wild_patterns_owned: Vec<_> =
15361577
sub_pat_tys.iter().map(|ty| Pat { ty, span: DUMMY_SP, kind: box PatKind::Wild }).collect();
15371578
let wild_patterns: Vec<_> = wild_patterns_owned.iter().collect();
1538-
let matrix =
1539-
Matrix(m.iter().filter_map(|r| specialize(cx, &r, &ctor, &wild_patterns)).collect());
1540-
match specialize(cx, v, &ctor, &wild_patterns) {
1579+
let matrix = matrix.specialize_constructor(cx, &ctor, &wild_patterns);
1580+
match v.specialize_constructor(cx, &ctor, &wild_patterns) {
15411581
Some(v) => match is_useful(cx, &matrix, &v, witness, hir_id) {
15421582
UsefulWithWitness(witnesses) => UsefulWithWitness(
15431583
witnesses
@@ -2013,7 +2053,7 @@ fn specialize<'p, 'a: 'p, 'q: 'p, 'tcx>(
20132053
) -> Option<PatStack<'p, 'tcx>> {
20142054
let pat = r.head();
20152055

2016-
let head = match *pat.kind {
2056+
let new_head = match *pat.kind {
20172057
PatKind::AscribeUserType { ref subpattern, .. } => {
20182058
specialize(cx, &PatStack::from_pattern(subpattern), constructor, wild_patterns)
20192059
}
@@ -2167,9 +2207,9 @@ fn specialize<'p, 'a: 'p, 'q: 'p, 'tcx>(
21672207
bug!("support for or-patterns has not been fully implemented yet.");
21682208
}
21692209
};
2170-
debug!("specialize({:#?}, {:#?}) = {:#?}", r.head(), wild_patterns, head);
2210+
debug!("specialize({:#?}, {:#?}) = {:#?}", r.head(), wild_patterns, new_head);
21712211

2172-
head.map(|head| {
2212+
new_head.map(|head| {
21732213
let mut head = head.0;
21742214
head.extend_from_slice(&r.0[1..]);
21752215
PatStack::from_vec(head)

0 commit comments

Comments
 (0)