diff options
| author | Nadrieril <nadrieril+git@gmail.com> | 2019-11-01 16:33:34 +0000 |
|---|---|---|
| committer | Nadrieril <nadrieril+git@gmail.com> | 2019-11-01 17:22:29 +0000 |
| commit | 23ca38ed958d4ef3416a77a76f773897e433117b (patch) | |
| tree | ac3bba3b3589e019b1bc6e7da2554f58f5809864 | |
| parent | 403d6bd995dc6a5e708dfe28f36e900ff94723e1 (diff) | |
| download | rust-23ca38ed958d4ef3416a77a76f773897e433117b.tar.gz rust-23ca38ed958d4ef3416a77a76f773897e433117b.zip | |
Factor out some pattern-stack related functions
| -rw-r--r-- | src/librustc_mir/hair/pattern/_match.rs | 64 |
1 files changed, 52 insertions, 12 deletions
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 8382ddeabc6..2bbe097047c 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -379,6 +379,25 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> { fn iter(&self) -> impl Iterator<Item = &Pat<'tcx>> { self.0.iter().map(|p| *p) } + + /// This computes `D(self)`. See top of the file for explanations. + fn specialize_wildcard(&self) -> Option<Self> { + if self.head().is_wildcard() { Some(self.to_tail()) } else { None } + } + + /// This computes `S(constructor, self)`. See top of the file for explanations. + fn specialize_constructor<'a, 'q>( + &self, + cx: &mut MatchCheckCtxt<'a, 'tcx>, + constructor: &Constructor<'tcx>, + wild_patterns: &[&'q Pat<'tcx>], + ) -> Option<PatStack<'q, 'tcx>> + where + 'a: 'q, + 'p: 'q, + { + specialize(cx, self, constructor, wild_patterns) + } } impl<'p, 'tcx> Default for PatStack<'p, 'tcx> { @@ -407,6 +426,30 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> { pub fn push(&mut self, row: PatStack<'p, 'tcx>) { self.0.push(row) } + + /// This computes `D(self)`. See top of the file for explanations. + fn specialize_wildcard(&self) -> Self { + self.0.iter().filter_map(|r| r.specialize_wildcard()).collect() + } + + /// This computes `S(constructor, self)`. See top of the file for explanations. + fn specialize_constructor<'a, 'q>( + &self, + cx: &mut MatchCheckCtxt<'a, 'tcx>, + constructor: &Constructor<'tcx>, + wild_patterns: &[&'q Pat<'tcx>], + ) -> Matrix<'q, 'tcx> + where + 'a: 'q, + 'p: 'q, + { + Matrix( + self.0 + .iter() + .filter_map(|r| r.specialize_constructor(cx, constructor, wild_patterns)) + .collect(), + ) + } } /// Pretty-printer for matrices of patterns, example: @@ -1423,11 +1466,9 @@ pub fn is_useful<'p, 'a, 'tcx>( .find(|result| result.is_useful()) .unwrap_or(NotUseful) } else { - let matrix = rows - .iter() - .filter_map(|r| if r.head().is_wildcard() { Some(r.to_tail()) } else { None }) - .collect(); - match is_useful(cx, &matrix, &v.to_tail(), witness, hir_id) { + let matrix = matrix.specialize_wildcard(); + let v = v.to_tail(); + match is_useful(cx, &matrix, &v, witness, hir_id) { UsefulWithWitness(pats) => { let cx = &*cx; // In this case, there's at least one "free" @@ -1523,7 +1564,7 @@ pub fn is_useful<'p, 'a, 'tcx>( /// to the specialised version of both the pattern matrix `P` and the new pattern `q`. fn is_useful_specialized<'p, 'a, 'tcx>( cx: &mut MatchCheckCtxt<'a, 'tcx>, - &Matrix(ref m): &Matrix<'p, 'tcx>, + matrix: &Matrix<'p, 'tcx>, v: &PatStack<'_, 'tcx>, ctor: Constructor<'tcx>, lty: Ty<'tcx>, @@ -1535,9 +1576,8 @@ fn is_useful_specialized<'p, 'a, 'tcx>( let wild_patterns_owned: Vec<_> = sub_pat_tys.iter().map(|ty| Pat { ty, span: DUMMY_SP, kind: box PatKind::Wild }).collect(); let wild_patterns: Vec<_> = wild_patterns_owned.iter().collect(); - let matrix = - Matrix(m.iter().filter_map(|r| specialize(cx, &r, &ctor, &wild_patterns)).collect()); - match specialize(cx, v, &ctor, &wild_patterns) { + let matrix = matrix.specialize_constructor(cx, &ctor, &wild_patterns); + match v.specialize_constructor(cx, &ctor, &wild_patterns) { Some(v) => match is_useful(cx, &matrix, &v, witness, hir_id) { UsefulWithWitness(witnesses) => UsefulWithWitness( witnesses @@ -2013,7 +2053,7 @@ fn specialize<'p, 'a: 'p, 'q: 'p, 'tcx>( ) -> Option<PatStack<'p, 'tcx>> { let pat = r.head(); - let head = match *pat.kind { + let new_head = match *pat.kind { PatKind::AscribeUserType { ref subpattern, .. } => { specialize(cx, &PatStack::from_pattern(subpattern), constructor, wild_patterns) } @@ -2167,9 +2207,9 @@ fn specialize<'p, 'a: 'p, 'q: 'p, 'tcx>( bug!("support for or-patterns has not been fully implemented yet."); } }; - debug!("specialize({:#?}, {:#?}) = {:#?}", r.head(), wild_patterns, head); + debug!("specialize({:#?}, {:#?}) = {:#?}", r.head(), wild_patterns, new_head); - head.map(|head| { + new_head.map(|head| { let mut head = head.0; head.extend_from_slice(&r.0[1..]); PatStack::from_vec(head) |
