@@ -342,7 +342,7 @@ pub struct PatStack<'p, 'tcx> {
342
342
// This caches the invocation of `pat_constructors` on the head of the stack. We avoid mutating
343
343
// `self` to be sure we don't keep an invalid cache around. Must be non-empty unless `patterns`
344
344
// is empty.
345
- head_ctors : SmallVec < [ Constructor < ' tcx > ; 1 ] > ,
345
+ head_ctor : Option < Constructor < ' tcx > > ,
346
346
}
347
347
348
348
impl < ' p , ' tcx > PatStack < ' p , ' tcx > {
@@ -351,15 +351,15 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
351
351
}
352
352
353
353
fn empty ( ) -> Self {
354
- PatStack { patterns : smallvec ! [ ] , head_ctors : smallvec ! [ ] }
354
+ PatStack { patterns : smallvec ! [ ] , head_ctor : None }
355
355
}
356
356
357
357
fn from_vec ( cx : & MatchCheckCtxt < ' _ , ' tcx > , patterns : SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ) -> Self {
358
358
if patterns. is_empty ( ) {
359
359
return PatStack :: empty ( ) ;
360
360
}
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 }
363
363
}
364
364
365
365
fn from_slice ( cx : & MatchCheckCtxt < ' _ , ' tcx > , s : & [ & ' p Pat < ' tcx > ] ) -> Self {
@@ -378,8 +378,8 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
378
378
self . patterns [ 0 ]
379
379
}
380
380
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 ( )
383
383
}
384
384
385
385
fn iter ( & self ) -> impl Iterator < Item = & Pat < ' tcx > > {
@@ -392,20 +392,17 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
392
392
cx : & MatchCheckCtxt < ' a , ' tcx > ,
393
393
constructor : & Constructor < ' tcx > ,
394
394
ctor_wild_subpatterns : & [ & ' q Pat < ' tcx > ] ,
395
- ) -> SmallVec < [ PatStack < ' q , ' tcx > ; 1 ] >
395
+ ) -> Option < PatStack < ' q , ' tcx > >
396
396
where
397
397
' a : ' q ,
398
398
' p : ' q ,
399
399
{
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
+ } ) ;
409
406
debug ! ( "specialize({:#?}, {:#?}) = {:#?}" , self , constructor, result) ;
410
407
result
411
408
}
@@ -435,7 +432,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
435
432
}
436
433
437
434
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 ( )
439
436
}
440
437
441
438
/// This computes `S(constructor, self)`. See top of the file for explanations.
@@ -452,7 +449,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
452
449
Matrix (
453
450
self . 0
454
451
. iter ( )
455
- . flat_map ( |r| r. specialize ( cx, constructor, ctor_wild_subpatterns) )
452
+ . filter_map ( |r| r. specialize ( cx, constructor, ctor_wild_subpatterns) )
456
453
. collect ( ) ,
457
454
)
458
455
}
@@ -707,8 +704,8 @@ impl<'tcx> Constructor<'tcx> {
707
704
let row_borders = head_ctors
708
705
. iter ( )
709
706
. 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) )
712
709
. flat_map ( |range| range_borders ( range) ) ;
713
710
let ctor_borders = range_borders ( ctor_range. clone ( ) ) ;
714
711
let mut borders: Vec < _ > = row_borders. chain ( ctor_borders) . collect ( ) ;
@@ -1024,7 +1021,7 @@ impl<'tcx> Constructor<'tcx> {
1024
1021
}
1025
1022
}
1026
1023
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) ;
1028
1025
let mut remaining_ranges: SmallVec < [ IntRange < ' tcx > ; 1 ] > = smallvec ! [ range] ;
1029
1026
1030
1027
// For each used ctor, subtract from the current set of constructors.
@@ -1763,12 +1760,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
1763
1760
1764
1761
debug ! ( "is_useful_expand_first_col: ty={:#?}, expanding {:#?}" , ty, v. head( ) ) ;
1765
1762
1766
- let v_constructors = v. head_ctors ( ) ;
1763
+ let v_constructor = v. head_ctors ( ) ;
1767
1764
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 ( ) {
1772
1766
debug ! ( "is_useful - shortcut because declared non-exhaustive" ) ;
1773
1767
// FIXME(#65157)
1774
1768
return Useful ;
@@ -1777,9 +1771,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
1777
1771
let matrix_head_ctors = matrix. head_ctors ( ) ;
1778
1772
debug ! ( "matrix_head_ctors = {:#?}" , matrix_head_ctors) ;
1779
1773
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 ( )
1783
1777
. map ( |c| is_useful_specialized ( cx, matrix, v, c, ty, witness_preference) )
1784
1778
. find ( |result| result. is_useful ( ) )
1785
1779
. unwrap_or ( NotUseful )
@@ -1816,41 +1810,41 @@ fn pat_constructors<'tcx>(
1816
1810
tcx : TyCtxt < ' tcx > ,
1817
1811
param_env : ty:: ParamEnv < ' tcx > ,
1818
1812
pat : & Pat < ' tcx > ,
1819
- ) -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
1813
+ ) -> Constructor < ' tcx > {
1820
1814
match * pat. kind {
1821
1815
PatKind :: AscribeUserType { ref subpattern, .. } => {
1822
1816
pat_constructors ( tcx, param_env, subpattern)
1823
1817
}
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 ,
1826
1820
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 )
1828
1822
}
1829
1823
PatKind :: Constant { value } => {
1830
1824
if let Some ( range) = IntRange :: from_const ( tcx, param_env, value) {
1831
- smallvec ! [ IntRange ( range) ]
1825
+ IntRange ( range)
1832
1826
} else {
1833
- smallvec ! [ ConstantValue ( value) ]
1827
+ ConstantValue ( value)
1834
1828
}
1835
1829
}
1836
1830
PatKind :: Range ( PatRange { lo, hi, end } ) => {
1837
1831
if let Some ( range) = IntRange :: from_const_range ( tcx, param_env, & lo, & hi, & end) {
1838
- smallvec ! [ IntRange ( range) ]
1832
+ IntRange ( range)
1839
1833
} else {
1840
- smallvec ! [ ConstantRange ( lo, hi, end) ]
1834
+ ConstantRange ( lo, hi, end)
1841
1835
}
1842
1836
}
1843
1837
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) ) ,
1845
1839
_ => span_bug ! ( pat. span, "bad ty {:?} for array pattern" , pat. ty) ,
1846
1840
} ,
1847
1841
PatKind :: Slice { ref prefix, ref slice, ref suffix } => {
1848
1842
let prefix = prefix. len ( ) as u64 ;
1849
1843
let suffix = suffix. len ( ) as u64 ;
1850
1844
if slice. is_some ( ) {
1851
- smallvec ! [ VarLenSlice ( prefix, suffix) ]
1845
+ VarLenSlice ( prefix, suffix)
1852
1846
} else {
1853
- smallvec ! [ FixedLenSlice ( prefix + suffix) ]
1847
+ FixedLenSlice ( prefix + suffix)
1854
1848
}
1855
1849
}
1856
1850
PatKind :: Or { .. } => {
@@ -2005,7 +1999,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2005
1999
mut pat : & ' q Pat < ' tcx > ,
2006
2000
constructor : & Constructor < ' tcx > ,
2007
2001
ctor_wild_subpatterns : & [ & ' p Pat < ' tcx > ] ,
2008
- ) -> SmallVec < [ PatStack < ' p , ' tcx > ; 1 ] > {
2002
+ ) -> Option < PatStack < ' p , ' tcx > > {
2009
2003
while let PatKind :: AscribeUserType { ref subpattern, .. } = * pat. kind {
2010
2004
pat = subpattern;
2011
2005
}
@@ -2018,32 +2012,32 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2018
2012
// If `constructor` is `MissingConstructors(_)`: by the invariant of MissingConstructors,
2019
2013
// we know that all non-wildcard constructors should be discarded.
2020
2014
return match * pat. kind {
2021
- PatKind :: Binding { .. } | PatKind :: Wild => smallvec ! [ PatStack :: empty( ) ] ,
2022
- _ => smallvec ! [ ] ,
2015
+ PatKind :: Binding { .. } | PatKind :: Wild => Some ( PatStack :: empty ( ) ) ,
2016
+ _ => None ,
2023
2017
} ;
2024
2018
}
2025
2019
2026
2020
match * pat. kind {
2027
2021
PatKind :: AscribeUserType { .. } => unreachable ! ( ) , // Handled above
2028
2022
2029
2023
PatKind :: Binding { .. } | PatKind :: Wild => {
2030
- smallvec ! [ PatStack :: from_slice( cx, ctor_wild_subpatterns) ]
2024
+ Some ( PatStack :: from_slice ( cx, ctor_wild_subpatterns) )
2031
2025
}
2032
2026
2033
2027
PatKind :: Variant { adt_def, variant_index, ref subpatterns, .. } => {
2034
2028
let ref variant = adt_def. variants [ variant_index] ;
2035
2029
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) )
2037
2031
} else {
2038
- smallvec ! [ ]
2032
+ None
2039
2033
}
2040
2034
}
2041
2035
2042
2036
PatKind :: Leaf { ref subpatterns } => {
2043
- smallvec ! [ patterns_for_variant( cx, subpatterns, ctor_wild_subpatterns) ]
2037
+ Some ( patterns_for_variant ( cx, subpatterns, ctor_wild_subpatterns) )
2044
2038
}
2045
2039
2046
- PatKind :: Deref { ref subpattern } => smallvec ! [ PatStack :: from_pattern( cx, subpattern) ] ,
2040
+ PatKind :: Deref { ref subpattern } => Some ( PatStack :: from_pattern ( cx, subpattern) ) ,
2047
2041
2048
2042
PatKind :: Constant { value } if constructor. is_slice ( ) => {
2049
2043
// 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>(
2064
2058
}
2065
2059
ConstValue :: ByRef { .. } => {
2066
2060
// FIXME(oli-obk): implement `deref` for `ConstValue`
2067
- return smallvec ! [ ] ;
2061
+ return None ;
2068
2062
}
2069
2063
_ => span_bug ! (
2070
2064
pat. span,
@@ -2085,7 +2079,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2085
2079
let layout = if let Ok ( layout) = cx. tcx . layout_of ( cx. param_env . and ( ty) ) {
2086
2080
layout
2087
2081
} else {
2088
- return smallvec ! [ ] ;
2082
+ return None ;
2089
2083
} ;
2090
2084
let ptr = Pointer :: new ( AllocId ( 0 ) , offset) ;
2091
2085
let stack: Option < SmallVec < _ > > = ( 0 ..n)
@@ -2100,11 +2094,11 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2100
2094
} )
2101
2095
. collect ( ) ;
2102
2096
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 ,
2105
2099
}
2106
2100
} else {
2107
- smallvec ! [ ]
2101
+ None
2108
2102
}
2109
2103
}
2110
2104
@@ -2113,9 +2107,9 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2113
2107
// - Single value: add a row if the pattern contains the constructor.
2114
2108
// - Range: add a row if the constructor intersects the pattern.
2115
2109
if let Some ( ps) = constructor_intersects_pattern ( cx, constructor, pat) {
2116
- smallvec ! [ ps ]
2110
+ Some ( ps )
2117
2111
} else {
2118
- smallvec ! [ ]
2112
+ None
2119
2113
}
2120
2114
}
2121
2115
@@ -2125,7 +2119,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2125
2119
let pat_len = prefix. len ( ) + suffix. len ( ) ;
2126
2120
if let Some ( slice_count) = ctor_wild_subpatterns. len ( ) . checked_sub ( pat_len) {
2127
2121
if slice_count == 0 || slice. is_some ( ) {
2128
- smallvec ! [ PatStack :: from_vec(
2122
+ Some ( PatStack :: from_vec (
2129
2123
cx,
2130
2124
prefix
2131
2125
. iter ( )
@@ -2138,12 +2132,12 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2138
2132
. chain ( suffix. iter ( ) ) ,
2139
2133
)
2140
2134
. collect ( ) ,
2141
- ) ]
2135
+ ) )
2142
2136
} else {
2143
- smallvec ! [ ]
2137
+ None
2144
2138
}
2145
2139
} else {
2146
- smallvec ! [ ]
2140
+ None
2147
2141
}
2148
2142
}
2149
2143
ConstantValue ( cv) => {
@@ -2156,8 +2150,8 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2156
2150
suffix,
2157
2151
cx. param_env ,
2158
2152
) {
2159
- Ok ( true ) => smallvec ! [ PatStack :: default ( ) ] ,
2160
- Ok ( false ) | Err ( ErrorReported ) => smallvec ! [ ] ,
2153
+ Ok ( true ) => Some ( PatStack :: default ( ) ) ,
2154
+ Ok ( false ) | Err ( ErrorReported ) => None ,
2161
2155
}
2162
2156
}
2163
2157
_ => span_bug ! ( pat. span, "unexpected ctor {:?} for slice pat" , constructor) ,
0 commit comments