@@ -342,16 +342,69 @@ impl<'tcx> Pat<'tcx> {
342
342
}
343
343
}
344
344
345
- /// A 2D matrix. Nx1 matrices are very common, which is why `SmallVec[_; 2]`
346
- /// works well for each row.
347
- pub struct Matrix < ' p , ' tcx > ( Vec < SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > > ) ;
345
+ /// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
346
+ /// works well.
347
+ #[ derive( Debug , Clone ) ]
348
+ pub struct PatStack < ' p , ' tcx > ( SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ) ;
349
+
350
+ impl < ' p , ' tcx > PatStack < ' p , ' tcx > {
351
+ pub fn from_pattern ( pat : & ' p Pat < ' tcx > ) -> Self {
352
+ PatStack ( smallvec ! [ pat] )
353
+ }
354
+
355
+ fn from_vec ( vec : SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ) -> Self {
356
+ PatStack ( vec)
357
+ }
358
+
359
+ fn from_slice ( s : & [ & ' p Pat < ' tcx > ] ) -> Self {
360
+ PatStack ( SmallVec :: from_slice ( s) )
361
+ }
362
+
363
+ fn is_empty ( & self ) -> bool {
364
+ self . 0 . is_empty ( )
365
+ }
366
+
367
+ fn len ( & self ) -> usize {
368
+ self . 0 . len ( )
369
+ }
370
+
371
+ fn head ( & self ) -> & ' p Pat < ' tcx > {
372
+ self . 0 [ 0 ]
373
+ }
374
+
375
+ fn to_tail ( & self ) -> Self {
376
+ PatStack :: from_slice ( & self . 0 [ 1 ..] )
377
+ }
378
+
379
+ fn iter ( & self ) -> impl Iterator < Item = & Pat < ' tcx > > {
380
+ self . 0 . iter ( ) . map ( |p| * p)
381
+ }
382
+ }
383
+
384
+ impl < ' p , ' tcx > Default for PatStack < ' p , ' tcx > {
385
+ fn default ( ) -> Self {
386
+ PatStack ( smallvec ! [ ] )
387
+ }
388
+ }
389
+
390
+ impl < ' p , ' tcx > FromIterator < & ' p Pat < ' tcx > > for PatStack < ' p , ' tcx > {
391
+ fn from_iter < T > ( iter : T ) -> Self
392
+ where
393
+ T : IntoIterator < Item = & ' p Pat < ' tcx > > ,
394
+ {
395
+ PatStack ( iter. into_iter ( ) . collect ( ) )
396
+ }
397
+ }
398
+
399
+ /// A 2D matrix.
400
+ pub struct Matrix < ' p , ' tcx > ( Vec < PatStack < ' p , ' tcx > > ) ;
348
401
349
402
impl < ' p , ' tcx > Matrix < ' p , ' tcx > {
350
403
pub fn empty ( ) -> Self {
351
404
Matrix ( vec ! [ ] )
352
405
}
353
406
354
- pub fn push ( & mut self , row : SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > ) {
407
+ pub fn push ( & mut self , row : PatStack < ' p , ' tcx > ) {
355
408
self . 0 . push ( row)
356
409
}
357
410
}
@@ -399,10 +452,10 @@ impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
399
452
}
400
453
}
401
454
402
- impl < ' p , ' tcx > FromIterator < SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > > for Matrix < ' p , ' tcx > {
455
+ impl < ' p , ' tcx > FromIterator < PatStack < ' p , ' tcx > > for Matrix < ' p , ' tcx > {
403
456
fn from_iter < T > ( iter : T ) -> Self
404
457
where
405
- T : IntoIterator < Item = SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > > ,
458
+ T : IntoIterator < Item = PatStack < ' p , ' tcx > > ,
406
459
{
407
460
Matrix ( iter. into_iter ( ) . collect ( ) )
408
461
}
@@ -1226,7 +1279,7 @@ fn compute_missing_ctors<'tcx>(
1226
1279
pub fn is_useful < ' p , ' a , ' tcx > (
1227
1280
cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
1228
1281
matrix : & Matrix < ' p , ' tcx > ,
1229
- v : & [ & Pat < ' tcx > ] ,
1282
+ v : & PatStack < ' _ , ' tcx > ,
1230
1283
witness : WitnessPreference ,
1231
1284
hir_id : HirId ,
1232
1285
) -> Usefulness < ' tcx > {
@@ -1253,9 +1306,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
1253
1306
1254
1307
let ( ty, span) = rows
1255
1308
. iter ( )
1256
- . map ( |r| ( r[ 0 ] . ty , r[ 0 ] . span ) )
1309
+ . map ( |r| ( r. head ( ) . ty , r. head ( ) . span ) )
1257
1310
. find ( |( ty, _) | !ty. references_error ( ) )
1258
- . unwrap_or ( ( v[ 0 ] . ty , v[ 0 ] . span ) ) ;
1311
+ . unwrap_or ( ( v. head ( ) . ty , v. head ( ) . span ) ) ;
1259
1312
let pcx = PatCtxt {
1260
1313
// TyErr is used to represent the type of wildcard patterns matching
1261
1314
// against inaccessible (private) fields of structs, so that we won't
@@ -1277,13 +1330,13 @@ pub fn is_useful<'p, 'a, 'tcx>(
1277
1330
// introducing uninhabited patterns for inaccessible fields. We
1278
1331
// need to figure out how to model that.
1279
1332
ty,
1280
- max_slice_length : max_slice_length ( cx, rows. iter ( ) . map ( |r| r[ 0 ] ) . chain ( Some ( v[ 0 ] ) ) ) ,
1333
+ max_slice_length : max_slice_length ( cx, rows. iter ( ) . map ( |r| r. head ( ) ) . chain ( Some ( v. head ( ) ) ) ) ,
1281
1334
span,
1282
1335
} ;
1283
1336
1284
- debug ! ( "is_useful_expand_first_col: pcx={:#?}, expanding {:#?}" , pcx, v[ 0 ] ) ;
1337
+ debug ! ( "is_useful_expand_first_col: pcx={:#?}, expanding {:#?}" , pcx, v. head ( ) ) ;
1285
1338
1286
- if let Some ( constructors) = pat_constructors ( cx, v[ 0 ] , pcx) {
1339
+ if let Some ( constructors) = pat_constructors ( cx, v. head ( ) , pcx) {
1287
1340
debug ! ( "is_useful - expanding constructors: {:#?}" , constructors) ;
1288
1341
split_grouped_constructors (
1289
1342
cx. tcx ,
@@ -1303,7 +1356,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
1303
1356
1304
1357
let used_ctors: Vec < Constructor < ' _ > > = rows
1305
1358
. iter ( )
1306
- . flat_map ( |row| pat_constructors ( cx, row[ 0 ] , pcx) . unwrap_or ( vec ! [ ] ) )
1359
+ . flat_map ( |row| pat_constructors ( cx, row. head ( ) , pcx) . unwrap_or ( vec ! [ ] ) )
1307
1360
. collect ( ) ;
1308
1361
debug ! ( "used_ctors = {:#?}" , used_ctors) ;
1309
1362
// `all_ctors` are all the constructors for the given type, which
@@ -1372,11 +1425,9 @@ pub fn is_useful<'p, 'a, 'tcx>(
1372
1425
} else {
1373
1426
let matrix = rows
1374
1427
. iter ( )
1375
- . filter_map ( |r| {
1376
- if r[ 0 ] . is_wildcard ( ) { Some ( SmallVec :: from_slice ( & r[ 1 ..] ) ) } else { None }
1377
- } )
1428
+ . filter_map ( |r| if r. head ( ) . is_wildcard ( ) { Some ( r. to_tail ( ) ) } else { None } )
1378
1429
. collect ( ) ;
1379
- match is_useful ( cx, & matrix, & v[ 1 .. ] , witness, hir_id) {
1430
+ match is_useful ( cx, & matrix, & v. to_tail ( ) , witness, hir_id) {
1380
1431
UsefulWithWitness ( pats) => {
1381
1432
let cx = & * cx;
1382
1433
// In this case, there's at least one "free"
@@ -1473,7 +1524,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
1473
1524
fn is_useful_specialized < ' p , ' a , ' tcx > (
1474
1525
cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
1475
1526
& Matrix ( ref m) : & Matrix < ' p , ' tcx > ,
1476
- v : & [ & Pat < ' tcx > ] ,
1527
+ v : & PatStack < ' _ , ' tcx > ,
1477
1528
ctor : Constructor < ' tcx > ,
1478
1529
lty : Ty < ' tcx > ,
1479
1530
witness : WitnessPreference ,
@@ -1787,7 +1838,7 @@ fn split_grouped_constructors<'p, 'tcx>(
1787
1838
let row_borders = m
1788
1839
. iter ( )
1789
1840
. flat_map ( |row| {
1790
- IntRange :: from_pat ( tcx, param_env, row[ 0 ] ) . map ( |r| ( r, row. len ( ) ) )
1841
+ IntRange :: from_pat ( tcx, param_env, row. head ( ) ) . map ( |r| ( r, row. len ( ) ) )
1791
1842
} )
1792
1843
. flat_map ( |( range, row_len) | {
1793
1844
let intersection = ctor_range. intersection ( & range) ;
@@ -1933,7 +1984,7 @@ fn patterns_for_variant<'p, 'a: 'p, 'tcx>(
1933
1984
subpatterns : & ' p [ FieldPat < ' tcx > ] ,
1934
1985
wild_patterns : & [ & ' p Pat < ' tcx > ] ,
1935
1986
is_non_exhaustive : bool ,
1936
- ) -> SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > {
1987
+ ) -> PatStack < ' p , ' tcx > {
1937
1988
let mut result = SmallVec :: from_slice ( wild_patterns) ;
1938
1989
1939
1990
for subpat in subpatterns {
@@ -1943,7 +1994,7 @@ fn patterns_for_variant<'p, 'a: 'p, 'tcx>(
1943
1994
}
1944
1995
1945
1996
debug ! ( "patterns_for_variant({:#?}, {:#?}) = {:#?}" , subpatterns, wild_patterns, result) ;
1946
- result
1997
+ PatStack :: from_vec ( result)
1947
1998
}
1948
1999
1949
2000
/// This is the main specialization step. It expands the first pattern in the given row
@@ -1954,20 +2005,20 @@ fn patterns_for_variant<'p, 'a: 'p, 'tcx>(
1954
2005
/// different patterns.
1955
2006
/// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
1956
2007
/// fields filled with wild patterns.
1957
- fn specialize < ' p , ' a : ' p , ' tcx > (
2008
+ fn specialize < ' p , ' a : ' p , ' q : ' p , ' tcx > (
1958
2009
cx : & mut MatchCheckCtxt < ' a , ' tcx > ,
1959
- r : & [ & ' p Pat < ' tcx > ] ,
2010
+ r : & PatStack < ' q , ' tcx > ,
1960
2011
constructor : & Constructor < ' tcx > ,
1961
2012
wild_patterns : & [ & ' p Pat < ' tcx > ] ,
1962
- ) -> Option < SmallVec < [ & ' p Pat < ' tcx > ; 2 ] > > {
1963
- let pat = & r [ 0 ] ;
2013
+ ) -> Option < PatStack < ' p , ' tcx > > {
2014
+ let pat = r . head ( ) ;
1964
2015
1965
2016
let head = match * pat. kind {
1966
2017
PatKind :: AscribeUserType { ref subpattern, .. } => {
1967
- specialize ( cx, :: std :: slice :: from_ref ( & subpattern) , constructor, wild_patterns)
2018
+ specialize ( cx, & PatStack :: from_pattern ( subpattern) , constructor, wild_patterns)
1968
2019
}
1969
2020
1970
- PatKind :: Binding { .. } | PatKind :: Wild => Some ( SmallVec :: from_slice ( wild_patterns) ) ,
2021
+ PatKind :: Binding { .. } | PatKind :: Wild => Some ( PatStack :: from_slice ( wild_patterns) ) ,
1971
2022
1972
2023
PatKind :: Variant { adt_def, variant_index, ref subpatterns, .. } => {
1973
2024
let ref variant = adt_def. variants [ variant_index] ;
@@ -1981,7 +2032,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
1981
2032
Some ( patterns_for_variant ( cx, subpatterns, wild_patterns, false ) )
1982
2033
}
1983
2034
1984
- PatKind :: Deref { ref subpattern } => Some ( smallvec ! [ subpattern] ) ,
2035
+ PatKind :: Deref { ref subpattern } => Some ( PatStack :: from_pattern ( subpattern) ) ,
1985
2036
1986
2037
PatKind :: Constant { value } if constructor. is_slice ( ) => {
1987
2038
// We extract an `Option` for the pointer because slices of zero
@@ -2051,7 +2102,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
2051
2102
let ( pat_lo, pat_hi) = pat. range . into_inner ( ) ;
2052
2103
let ( ctor_lo, ctor_hi) = ctor. range . into_inner ( ) ;
2053
2104
assert ! ( pat_lo <= ctor_lo && ctor_hi <= pat_hi) ;
2054
- smallvec ! [ ]
2105
+ PatStack :: default ( )
2055
2106
} ) ,
2056
2107
_ => None ,
2057
2108
}
@@ -2062,7 +2113,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
2062
2113
// range so intersection actually devolves into being covered
2063
2114
// by the pattern.
2064
2115
match constructor_covered_by_range ( cx. tcx , cx. param_env , constructor, pat) {
2065
- Ok ( true ) => Some ( smallvec ! [ ] ) ,
2116
+ Ok ( true ) => Some ( PatStack :: default ( ) ) ,
2066
2117
Ok ( false ) | Err ( ErrorReported ) => None ,
2067
2118
}
2068
2119
}
@@ -2104,7 +2155,7 @@ fn specialize<'p, 'a: 'p, 'tcx>(
2104
2155
suffix,
2105
2156
cx. param_env ,
2106
2157
) {
2107
- Ok ( true ) => Some ( smallvec ! [ ] ) ,
2158
+ Ok ( true ) => Some ( PatStack :: default ( ) ) ,
2108
2159
Ok ( false ) => None ,
2109
2160
Err ( ErrorReported ) => None ,
2110
2161
}
@@ -2116,10 +2167,11 @@ fn specialize<'p, 'a: 'p, 'tcx>(
2116
2167
bug ! ( "support for or-patterns has not been fully implemented yet." ) ;
2117
2168
}
2118
2169
} ;
2119
- debug ! ( "specialize({:#?}, {:#?}) = {:#?}" , r[ 0 ] , wild_patterns, head) ;
2170
+ debug ! ( "specialize({:#?}, {:#?}) = {:#?}" , r. head ( ) , wild_patterns, head) ;
2120
2171
2121
- head. map ( |mut head| {
2122
- head. extend_from_slice ( & r[ 1 ..] ) ;
2123
- head
2172
+ head. map ( |head| {
2173
+ let mut head = head. 0 ;
2174
+ head. extend_from_slice ( & r. 0 [ 1 ..] ) ;
2175
+ PatStack :: from_vec ( head)
2124
2176
} )
2125
2177
}
0 commit comments