@@ -190,6 +190,7 @@ use syntax_pos::{Span, DUMMY_SP};
190190
191191use arena:: TypedArena ;
192192
193+ use smallvec:: { SmallVec , smallvec} ;
193194use std:: cmp:: { self , Ordering , min, max} ;
194195use std:: fmt;
195196use std:: iter:: { FromIterator , IntoIterator } ;
@@ -237,14 +238,16 @@ impl<'tcx> Pattern<'tcx> {
237238 }
238239}
239240
240- pub struct Matrix < ' a , ' tcx : ' a > ( Vec < Vec < & ' a Pattern < ' tcx > > > ) ;
241+ /// A 2D matrix. Nx1 matrices are very common, which is why `SmallVec[_; 2]`
242+ /// works well for each row.
243+ pub struct Matrix < ' p , ' tcx : ' p > ( Vec < SmallVec < [ & ' p Pattern < ' tcx > ; 2 ] > > ) ;
241244
242- impl < ' a , ' tcx > Matrix < ' a , ' tcx > {
245+ impl < ' p , ' tcx > Matrix < ' p , ' tcx > {
243246 pub fn empty ( ) -> Self {
244247 Matrix ( vec ! [ ] )
245248 }
246249
247- pub fn push ( & mut self , row : Vec < & ' a Pattern < ' tcx > > ) {
250+ pub fn push ( & mut self , row : SmallVec < [ & ' p Pattern < ' tcx > ; 2 ] > ) {
248251 self . 0 . push ( row)
249252 }
250253}
@@ -261,7 +264,7 @@ impl<'a, 'tcx> Matrix<'a, 'tcx> {
261264/// ++++++++++++++++++++++++++
262265/// + _ + [_, _, ..tail] +
263266/// ++++++++++++++++++++++++++
264- impl < ' a , ' tcx > fmt:: Debug for Matrix < ' a , ' tcx > {
267+ impl < ' p , ' tcx > fmt:: Debug for Matrix < ' p , ' tcx > {
265268 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
266269 write ! ( f, "\n " ) ?;
267270
@@ -293,8 +296,9 @@ impl<'a, 'tcx> fmt::Debug for Matrix<'a, 'tcx> {
293296 }
294297}
295298
296- impl < ' a , ' tcx > FromIterator < Vec < & ' a Pattern < ' tcx > > > for Matrix < ' a , ' tcx > {
297- fn from_iter < T : IntoIterator < Item =Vec < & ' a Pattern < ' tcx > > > > ( iter : T ) -> Self
299+ impl < ' p , ' tcx > FromIterator < SmallVec < [ & ' p Pattern < ' tcx > ; 2 ] > > for Matrix < ' p , ' tcx > {
300+ fn from_iter < T > ( iter : T ) -> Self
301+ where T : IntoIterator < Item =SmallVec < [ & ' p Pattern < ' tcx > ; 2 ] > >
298302 {
299303 Matrix ( iter. into_iter ( ) . collect ( ) )
300304 }
@@ -998,7 +1002,7 @@ fn compute_missing_ctors<'a, 'tcx: 'a>(
9981002/// matrix isn't exhaustive).
9991003pub fn is_useful < ' p , ' a : ' p , ' tcx : ' a > ( cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
10001004 matrix : & Matrix < ' p , ' tcx > ,
1001- v : & [ & ' p Pattern < ' tcx > ] ,
1005+ v : & [ & Pattern < ' tcx > ] ,
10021006 witness : WitnessPreference )
10031007 -> Usefulness < ' tcx > {
10041008 let & Matrix ( ref rows) = matrix;
@@ -1108,7 +1112,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
11081112 } else {
11091113 let matrix = rows. iter ( ) . filter_map ( |r| {
11101114 if r[ 0 ] . is_wildcard ( ) {
1111- Some ( r[ 1 ..] . to_vec ( ) )
1115+ Some ( SmallVec :: from_slice ( & r[ 1 ..] ) )
11121116 } else {
11131117 None
11141118 }
@@ -1199,10 +1203,10 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
11991203
12001204/// A shorthand for the `U(S(c, P), S(c, q))` operation from the paper. I.e., `is_useful` applied
12011205/// to the specialised version of both the pattern matrix `P` and the new pattern `q`.
1202- fn is_useful_specialized < ' p , ' a : ' p , ' tcx : ' a > (
1206+ fn is_useful_specialized < ' p , ' a : ' p , ' tcx : ' a > (
12031207 cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
12041208 & Matrix ( ref m) : & Matrix < ' p , ' tcx > ,
1205- v : & [ & ' p Pattern < ' tcx > ] ,
1209+ v : & [ & Pattern < ' tcx > ] ,
12061210 ctor : Constructor < ' tcx > ,
12071211 lty : Ty < ' tcx > ,
12081212 witness : WitnessPreference ,
@@ -1521,15 +1525,15 @@ fn constructor_intersects_pattern<'p, 'a: 'p, 'tcx: 'a>(
15211525 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
15221526 ctor : & Constructor < ' tcx > ,
15231527 pat : & ' p Pattern < ' tcx > ,
1524- ) -> Option < Vec < & ' p Pattern < ' tcx > > > {
1528+ ) -> Option < SmallVec < [ & ' p Pattern < ' tcx > ; 2 ] > > {
15251529 if should_treat_range_exhaustively ( tcx, ctor) {
15261530 match ( IntRange :: from_ctor ( tcx, ctor) , IntRange :: from_pat ( tcx, pat) ) {
15271531 ( Some ( ctor) , Some ( pat) ) => {
15281532 ctor. intersection ( & pat) . map ( |_| {
15291533 let ( pat_lo, pat_hi) = pat. range . into_inner ( ) ;
15301534 let ( ctor_lo, ctor_hi) = ctor. range . into_inner ( ) ;
15311535 assert ! ( pat_lo <= ctor_lo && ctor_hi <= pat_hi) ;
1532- vec ! [ ]
1536+ smallvec ! [ ]
15331537 } )
15341538 }
15351539 _ => None ,
@@ -1539,7 +1543,7 @@ fn constructor_intersects_pattern<'p, 'a: 'p, 'tcx: 'a>(
15391543 // conveniently handled by `IntRange`. For these cases, the constructor may not be a range
15401544 // so intersection actually devolves into being covered by the pattern.
15411545 match constructor_covered_by_range ( tcx, ctor, pat) {
1542- Ok ( true ) => Some ( vec ! [ ] ) ,
1546+ Ok ( true ) => Some ( smallvec ! [ ] ) ,
15431547 Ok ( false ) | Err ( ErrorReported ) => None ,
15441548 }
15451549 }
@@ -1610,9 +1614,9 @@ fn constructor_covered_by_range<'a, 'tcx>(
16101614fn patterns_for_variant < ' p , ' a : ' p , ' tcx : ' a > (
16111615 subpatterns : & ' p [ FieldPattern < ' tcx > ] ,
16121616 wild_patterns : & [ & ' p Pattern < ' tcx > ] )
1613- -> Vec < & ' p Pattern < ' tcx > >
1617+ -> SmallVec < [ & ' p Pattern < ' tcx > ; 2 ] >
16141618{
1615- let mut result = wild_patterns . to_owned ( ) ;
1619+ let mut result = SmallVec :: from_slice ( wild_patterns ) ;
16161620
16171621 for subpat in subpatterns {
16181622 result[ subpat. field . index ( ) ] = & subpat. pattern ;
@@ -1635,15 +1639,16 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
16351639 r : & [ & ' p Pattern < ' tcx > ] ,
16361640 constructor : & Constructor < ' tcx > ,
16371641 wild_patterns : & [ & ' p Pattern < ' tcx > ] ,
1638- ) -> Option < Vec < & ' p Pattern < ' tcx > > > {
1642+ ) -> Option < SmallVec < [ & ' p Pattern < ' tcx > ; 2 ] > > {
16391643 let pat = & r[ 0 ] ;
16401644
1641- let head: Option < Vec < & Pattern > > = match * pat. kind {
1642- PatternKind :: AscribeUserType { ref subpattern, .. } =>
1643- specialize ( cx, :: std:: slice:: from_ref ( & subpattern) , constructor, wild_patterns) ,
1645+ let head = match * pat. kind {
1646+ PatternKind :: AscribeUserType { ref subpattern, .. } => {
1647+ specialize ( cx, :: std:: slice:: from_ref ( & subpattern) , constructor, wild_patterns)
1648+ }
16441649
16451650 PatternKind :: Binding { .. } | PatternKind :: Wild => {
1646- Some ( wild_patterns . to_owned ( ) )
1651+ Some ( SmallVec :: from_slice ( wild_patterns ) )
16471652 }
16481653
16491654 PatternKind :: Variant { adt_def, variant_index, ref subpatterns, .. } => {
@@ -1660,7 +1665,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
16601665 }
16611666
16621667 PatternKind :: Deref { ref subpattern } => {
1663- Some ( vec ! [ subpattern] )
1668+ Some ( smallvec ! [ subpattern] )
16641669 }
16651670
16661671 PatternKind :: Constant { value } => {
@@ -1696,7 +1701,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
16961701 if wild_patterns. len ( ) as u64 == n {
16971702 // convert a constant slice/array pattern to a list of patterns.
16981703 match ( n, opt_ptr) {
1699- ( 0 , _) => Some ( Vec :: new ( ) ) ,
1704+ ( 0 , _) => Some ( SmallVec :: new ( ) ) ,
17001705 ( _, Some ( ptr) ) => {
17011706 let alloc = cx. tcx . alloc_map . lock ( ) . unwrap_memory ( ptr. alloc_id ) ;
17021707 let layout = cx. tcx . layout_of ( cx. param_env . and ( ty) ) . ok ( ) ?;
@@ -1765,7 +1770,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
17651770 match slice_pat_covered_by_constructor (
17661771 cx. tcx , pat. span , constructor, prefix, slice, suffix
17671772 ) {
1768- Ok ( true ) => Some ( vec ! [ ] ) ,
1773+ Ok ( true ) => Some ( smallvec ! [ ] ) ,
17691774 Ok ( false ) => None ,
17701775 Err ( ErrorReported ) => None
17711776 }
0 commit comments