@@ -342,7 +342,7 @@ pub struct PatStack<'p, 'tcx> {
342342 // This caches the invocation of `pat_constructors` on the head of the stack. We avoid mutating
343343 // `self` to be sure we don't keep an invalid cache around. Must be non-empty unless `patterns`
344344 // is empty.
345- head_ctors : SmallVec < [ Constructor < ' tcx > ; 1 ] > ,
345+ head_ctor : Option < Constructor < ' tcx > > ,
346346}
347347
348348impl < ' p , ' tcx > PatStack < ' p , ' tcx > {
@@ -351,15 +351,15 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
351351 }
352352
353353 fn empty ( ) -> Self {
354- PatStack { patterns : smallvec ! [ ] , head_ctors : smallvec ! [ ] }
354+ PatStack { patterns : smallvec ! [ ] , head_ctor : None }
355355 }
356356
357357 fn from_vec ( cx : & MatchCheckCtxt < ' _ , ' tcx > , patterns : SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ) -> Self {
358358 if patterns. is_empty ( ) {
359359 return PatStack :: empty ( ) ;
360360 }
361- let head_ctors = pat_constructors ( cx. tcx , cx. param_env , patterns[ 0 ] ) ;
362- PatStack { patterns, head_ctors }
361+ let head_ctor = Some ( pat_constructors ( cx. tcx , cx. param_env , patterns[ 0 ] ) ) ;
362+ PatStack { patterns, head_ctor }
363363 }
364364
365365 fn from_slice ( cx : & MatchCheckCtxt < ' _ , ' tcx > , s : & [ & ' p Pat < ' tcx > ] ) -> Self {
@@ -378,8 +378,8 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
378378 self . patterns [ 0 ]
379379 }
380380
381- fn head_ctors ( & self ) -> & SmallVec < [ Constructor < ' tcx > ; 1 ] > {
382- & self . head_ctors
381+ fn head_ctors ( & self ) -> & Constructor < ' tcx > {
382+ self . head_ctor . as_ref ( ) . unwrap ( )
383383 }
384384
385385 fn iter ( & self ) -> impl Iterator < Item = & Pat < ' tcx > > {
@@ -392,20 +392,17 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
392392 cx : & MatchCheckCtxt < ' a , ' tcx > ,
393393 constructor : & Constructor < ' tcx > ,
394394 ctor_wild_subpatterns : & [ & ' q Pat < ' tcx > ] ,
395- ) -> SmallVec < [ PatStack < ' q , ' tcx > ; 1 ] >
395+ ) -> Option < PatStack < ' q , ' tcx > >
396396 where
397397 ' a : ' q ,
398398 ' p : ' q ,
399399 {
400- let new_heads = specialize_one_pattern ( cx, self . head ( ) , constructor, ctor_wild_subpatterns) ;
401- let result = new_heads
402- . into_iter ( )
403- . map ( |new_head| {
404- let mut pats = new_head. patterns ;
405- pats. extend_from_slice ( & self . patterns [ 1 ..] ) ;
406- PatStack :: from_vec ( cx, pats)
407- } )
408- . collect ( ) ;
400+ let new_head = specialize_one_pattern ( cx, self . head ( ) , constructor, ctor_wild_subpatterns) ;
401+ let result = new_head. map ( |new_head| {
402+ let mut pats = new_head. patterns ;
403+ pats. extend_from_slice ( & self . patterns [ 1 ..] ) ;
404+ PatStack :: from_vec ( cx, pats)
405+ } ) ;
409406 debug ! ( "specialize({:#?}, {:#?}) = {:#?}" , self , constructor, result) ;
410407 result
411408 }
@@ -435,7 +432,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
435432 }
436433
437434 fn head_ctors ( & self ) -> Vec < & Constructor < ' tcx > > {
438- self . 0 . iter ( ) . flat_map ( |r| r. head_ctors ( ) ) . filter ( |ctor| !ctor. is_wildcard ( ) ) . collect ( )
435+ self . 0 . iter ( ) . map ( |r| r. head_ctors ( ) ) . filter ( |ctor| !ctor. is_wildcard ( ) ) . collect ( )
439436 }
440437
441438 /// This computes `S(constructor, self)`. See top of the file for explanations.
@@ -452,7 +449,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
452449 Matrix (
453450 self . 0
454451 . iter ( )
455- . flat_map ( |r| r. specialize ( cx, constructor, ctor_wild_subpatterns) )
452+ . filter_map ( |r| r. specialize ( cx, constructor, ctor_wild_subpatterns) )
456453 . collect ( ) ,
457454 )
458455 }
@@ -707,8 +704,8 @@ impl<'tcx> Constructor<'tcx> {
707704 let row_borders = head_ctors
708705 . iter ( )
709706 . map ( |c| * c)
710- . flat_map ( IntRange :: from_ctor)
711- . flat_map ( |range| ctor_range. intersection ( cx. tcx , & range) )
707+ . filter_map ( IntRange :: from_ctor)
708+ . filter_map ( |range| ctor_range. intersection ( cx. tcx , & range) )
712709 . flat_map ( |range| range_borders ( range) ) ;
713710 let ctor_borders = range_borders ( ctor_range. clone ( ) ) ;
714711 let mut borders: Vec < _ > = row_borders. chain ( ctor_borders) . collect ( ) ;
@@ -1024,7 +1021,7 @@ impl<'tcx> Constructor<'tcx> {
10241021 }
10251022 }
10261023 IntRange ( range) => {
1027- let used_ranges = used_ctors. iter ( ) . flat_map ( IntRange :: from_ctor) ;
1024+ let used_ranges = used_ctors. iter ( ) . filter_map ( IntRange :: from_ctor) ;
10281025 let mut remaining_ranges: SmallVec < [ IntRange < ' tcx > ; 1 ] > = smallvec ! [ range] ;
10291026
10301027 // For each used ctor, subtract from the current set of constructors.
@@ -1763,12 +1760,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
17631760
17641761 debug ! ( "is_useful_expand_first_col: ty={:#?}, expanding {:#?}" , ty, v. head( ) ) ;
17651762
1766- let v_constructors = v. head_ctors ( ) ;
1763+ let v_constructor = v. head_ctors ( ) ;
17671764
1768- if cx. is_non_exhaustive_variant ( v. head ( ) )
1769- && !cx. is_local ( ty)
1770- && !v_constructors. iter ( ) . any ( |ctor| ctor. is_wildcard ( ) )
1771- {
1765+ if cx. is_non_exhaustive_variant ( v. head ( ) ) && !cx. is_local ( ty) && !v_constructor. is_wildcard ( ) {
17721766 debug ! ( "is_useful - shortcut because declared non-exhaustive" ) ;
17731767 // FIXME(#65157)
17741768 return Useful ;
@@ -1777,9 +1771,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
17771771 let matrix_head_ctors = matrix. head_ctors ( ) ;
17781772 debug ! ( "matrix_head_ctors = {:#?}" , matrix_head_ctors) ;
17791773
1780- v_constructors
1781- . iter ( )
1782- . flat_map ( |ctor| ctor . split_meta_constructor ( cx , ty , & matrix_head_ctors ) )
1774+ v_constructor
1775+ . split_meta_constructor ( cx , ty , & matrix_head_ctors )
1776+ . into_iter ( )
17831777 . map ( |c| is_useful_specialized ( cx, matrix, v, c, ty, witness_preference) )
17841778 . find ( |result| result. is_useful ( ) )
17851779 . unwrap_or ( NotUseful )
@@ -1816,41 +1810,41 @@ fn pat_constructors<'tcx>(
18161810 tcx : TyCtxt < ' tcx > ,
18171811 param_env : ty:: ParamEnv < ' tcx > ,
18181812 pat : & Pat < ' tcx > ,
1819- ) -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
1813+ ) -> Constructor < ' tcx > {
18201814 match * pat. kind {
18211815 PatKind :: AscribeUserType { ref subpattern, .. } => {
18221816 pat_constructors ( tcx, param_env, subpattern)
18231817 }
1824- PatKind :: Binding { .. } | PatKind :: Wild => smallvec ! [ Wildcard ] ,
1825- PatKind :: Leaf { .. } | PatKind :: Deref { .. } => smallvec ! [ Single ] ,
1818+ PatKind :: Binding { .. } | PatKind :: Wild => Wildcard ,
1819+ PatKind :: Leaf { .. } | PatKind :: Deref { .. } => Single ,
18261820 PatKind :: Variant { adt_def, variant_index, .. } => {
1827- smallvec ! [ Variant ( adt_def. variants[ variant_index] . def_id) ]
1821+ Variant ( adt_def. variants [ variant_index] . def_id )
18281822 }
18291823 PatKind :: Constant { value } => {
18301824 if let Some ( range) = IntRange :: from_const ( tcx, param_env, value) {
1831- smallvec ! [ IntRange ( range) ]
1825+ IntRange ( range)
18321826 } else {
1833- smallvec ! [ ConstantValue ( value) ]
1827+ ConstantValue ( value)
18341828 }
18351829 }
18361830 PatKind :: Range ( PatRange { lo, hi, end } ) => {
18371831 if let Some ( range) = IntRange :: from_const_range ( tcx, param_env, & lo, & hi, & end) {
1838- smallvec ! [ IntRange ( range) ]
1832+ IntRange ( range)
18391833 } else {
1840- smallvec ! [ ConstantRange ( lo, hi, end) ]
1834+ ConstantRange ( lo, hi, end)
18411835 }
18421836 }
18431837 PatKind :: Array { .. } => match pat. ty . kind {
1844- ty:: Array ( _, length) => smallvec ! [ FixedLenSlice ( length. eval_usize( tcx, param_env) ) ] ,
1838+ ty:: Array ( _, length) => FixedLenSlice ( length. eval_usize ( tcx, param_env) ) ,
18451839 _ => span_bug ! ( pat. span, "bad ty {:?} for array pattern" , pat. ty) ,
18461840 } ,
18471841 PatKind :: Slice { ref prefix, ref slice, ref suffix } => {
18481842 let prefix = prefix. len ( ) as u64 ;
18491843 let suffix = suffix. len ( ) as u64 ;
18501844 if slice. is_some ( ) {
1851- smallvec ! [ VarLenSlice ( prefix, suffix) ]
1845+ VarLenSlice ( prefix, suffix)
18521846 } else {
1853- smallvec ! [ FixedLenSlice ( prefix + suffix) ]
1847+ FixedLenSlice ( prefix + suffix)
18541848 }
18551849 }
18561850 PatKind :: Or { .. } => {
@@ -2005,7 +1999,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
20051999 mut pat : & ' q Pat < ' tcx > ,
20062000 constructor : & Constructor < ' tcx > ,
20072001 ctor_wild_subpatterns : & [ & ' p Pat < ' tcx > ] ,
2008- ) -> SmallVec < [ PatStack < ' p , ' tcx > ; 1 ] > {
2002+ ) -> Option < PatStack < ' p , ' tcx > > {
20092003 while let PatKind :: AscribeUserType { ref subpattern, .. } = * pat. kind {
20102004 pat = subpattern;
20112005 }
@@ -2018,32 +2012,32 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
20182012 // If `constructor` is `MissingConstructors(_)`: by the invariant of MissingConstructors,
20192013 // we know that all non-wildcard constructors should be discarded.
20202014 return match * pat. kind {
2021- PatKind :: Binding { .. } | PatKind :: Wild => smallvec ! [ PatStack :: empty( ) ] ,
2022- _ => smallvec ! [ ] ,
2015+ PatKind :: Binding { .. } | PatKind :: Wild => Some ( PatStack :: empty ( ) ) ,
2016+ _ => None ,
20232017 } ;
20242018 }
20252019
20262020 match * pat. kind {
20272021 PatKind :: AscribeUserType { .. } => unreachable ! ( ) , // Handled above
20282022
20292023 PatKind :: Binding { .. } | PatKind :: Wild => {
2030- smallvec ! [ PatStack :: from_slice( cx, ctor_wild_subpatterns) ]
2024+ Some ( PatStack :: from_slice ( cx, ctor_wild_subpatterns) )
20312025 }
20322026
20332027 PatKind :: Variant { adt_def, variant_index, ref subpatterns, .. } => {
20342028 let ref variant = adt_def. variants [ variant_index] ;
20352029 if Variant ( variant. def_id ) == * constructor {
2036- smallvec ! [ patterns_for_variant( cx, subpatterns, ctor_wild_subpatterns) ]
2030+ Some ( patterns_for_variant ( cx, subpatterns, ctor_wild_subpatterns) )
20372031 } else {
2038- smallvec ! [ ]
2032+ None
20392033 }
20402034 }
20412035
20422036 PatKind :: Leaf { ref subpatterns } => {
2043- smallvec ! [ patterns_for_variant( cx, subpatterns, ctor_wild_subpatterns) ]
2037+ Some ( patterns_for_variant ( cx, subpatterns, ctor_wild_subpatterns) )
20442038 }
20452039
2046- PatKind :: Deref { ref subpattern } => smallvec ! [ PatStack :: from_pattern( cx, subpattern) ] ,
2040+ PatKind :: Deref { ref subpattern } => Some ( PatStack :: from_pattern ( cx, subpattern) ) ,
20472041
20482042 PatKind :: Constant { value } if constructor. is_slice ( ) => {
20492043 // We extract an `Option` for the pointer because slices of zero
@@ -2064,7 +2058,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
20642058 }
20652059 ConstValue :: ByRef { .. } => {
20662060 // FIXME(oli-obk): implement `deref` for `ConstValue`
2067- return smallvec ! [ ] ;
2061+ return None ;
20682062 }
20692063 _ => span_bug ! (
20702064 pat. span,
@@ -2085,7 +2079,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
20852079 let layout = if let Ok ( layout) = cx. tcx . layout_of ( cx. param_env . and ( ty) ) {
20862080 layout
20872081 } else {
2088- return smallvec ! [ ] ;
2082+ return None ;
20892083 } ;
20902084 let ptr = Pointer :: new ( AllocId ( 0 ) , offset) ;
20912085 let stack: Option < SmallVec < _ > > = ( 0 ..n)
@@ -2100,11 +2094,11 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
21002094 } )
21012095 . collect ( ) ;
21022096 match stack {
2103- Some ( v) => smallvec ! [ PatStack :: from_vec( cx, v) ] ,
2104- None => smallvec ! [ ] ,
2097+ Some ( v) => Some ( PatStack :: from_vec ( cx, v) ) ,
2098+ None => None ,
21052099 }
21062100 } else {
2107- smallvec ! [ ]
2101+ None
21082102 }
21092103 }
21102104
@@ -2113,9 +2107,9 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
21132107 // - Single value: add a row if the pattern contains the constructor.
21142108 // - Range: add a row if the constructor intersects the pattern.
21152109 if let Some ( ps) = constructor_intersects_pattern ( cx, constructor, pat) {
2116- smallvec ! [ ps ]
2110+ Some ( ps )
21172111 } else {
2118- smallvec ! [ ]
2112+ None
21192113 }
21202114 }
21212115
@@ -2125,7 +2119,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
21252119 let pat_len = prefix. len ( ) + suffix. len ( ) ;
21262120 if let Some ( slice_count) = ctor_wild_subpatterns. len ( ) . checked_sub ( pat_len) {
21272121 if slice_count == 0 || slice. is_some ( ) {
2128- smallvec ! [ PatStack :: from_vec(
2122+ Some ( PatStack :: from_vec (
21292123 cx,
21302124 prefix
21312125 . iter ( )
@@ -2138,12 +2132,12 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
21382132 . chain ( suffix. iter ( ) ) ,
21392133 )
21402134 . collect ( ) ,
2141- ) ]
2135+ ) )
21422136 } else {
2143- smallvec ! [ ]
2137+ None
21442138 }
21452139 } else {
2146- smallvec ! [ ]
2140+ None
21472141 }
21482142 }
21492143 ConstantValue ( cv) => {
@@ -2156,8 +2150,8 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
21562150 suffix,
21572151 cx. param_env ,
21582152 ) {
2159- Ok ( true ) => smallvec ! [ PatStack :: default ( ) ] ,
2160- Ok ( false ) | Err ( ErrorReported ) => smallvec ! [ ] ,
2153+ Ok ( true ) => Some ( PatStack :: default ( ) ) ,
2154+ Ok ( false ) | Err ( ErrorReported ) => None ,
21612155 }
21622156 }
21632157 _ => span_bug ! ( pat. span, "unexpected ctor {:?} for slice pat" , constructor) ,
0 commit comments