@@ -309,13 +309,15 @@ pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
309
309
/// outside it's module and should not be matchable with an empty match
310
310
/// statement.
311
311
pub module : DefId ,
312
+ param_env : ty:: ParamEnv < ' tcx > ,
312
313
pub pattern_arena : & ' a TypedArena < Pattern < ' tcx > > ,
313
314
pub byte_array_map : FxHashMap < * const Pattern < ' tcx > , Vec < & ' a Pattern < ' tcx > > > ,
314
315
}
315
316
316
317
impl < ' a , ' tcx > MatchCheckCtxt < ' a , ' tcx > {
317
318
pub fn create_and_enter < F , R > (
318
319
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
320
+ param_env : ty:: ParamEnv < ' tcx > ,
319
321
module : DefId ,
320
322
f : F ) -> R
321
323
where F : for < ' b > FnOnce ( MatchCheckCtxt < ' b , ' tcx > ) -> R
@@ -324,6 +326,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
324
326
325
327
f ( MatchCheckCtxt {
326
328
tcx,
329
+ param_env,
327
330
module,
328
331
pattern_arena : & pattern_arena,
329
332
byte_array_map : FxHashMap :: default ( ) ,
@@ -1668,17 +1671,14 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
1668
1671
// necessarily point to memory, they are usually just integers. The only time
1669
1672
// they should be pointing to memory is when they are subslices of nonzero
1670
1673
// slices
1671
- let ( opt_ptr, data_len) = match value. ty . builtin_deref ( false ) . unwrap ( ) . ty . sty {
1672
- ty:: TyKind :: Array ( t, n) => {
1673
- assert ! ( t == cx. tcx. types. u8 ) ;
1674
- ( value. to_ptr ( ) , n. unwrap_usize ( cx. tcx ) )
1675
- } ,
1674
+ let ( opt_ptr, n, ty) = match value. ty . builtin_deref ( false ) . unwrap ( ) . ty . sty {
1675
+ ty:: TyKind :: Array ( t, n) => ( value. to_ptr ( ) , n. unwrap_usize ( cx. tcx ) , t) ,
1676
1676
ty:: TyKind :: Slice ( t) => {
1677
- assert ! ( t == cx. tcx. types. u8 ) ;
1678
1677
match value. val {
1679
1678
ConstValue :: ScalarPair ( ptr, n) => (
1680
1679
ptr. to_ptr ( ) . ok ( ) ,
1681
- n. to_bits ( cx. tcx . data_layout . pointer_size ) . unwrap ( ) as u64
1680
+ n. to_bits ( cx. tcx . data_layout . pointer_size ) . unwrap ( ) as u64 ,
1681
+ t,
1682
1682
) ,
1683
1683
_ => span_bug ! (
1684
1684
pat. span,
@@ -1694,26 +1694,27 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
1694
1694
constructor,
1695
1695
) ,
1696
1696
} ;
1697
- if wild_patterns. len ( ) as u64 == data_len {
1698
- // convert a byte-string pattern to a list of u8 patterns.
1699
- match ( data_len , opt_ptr) {
1697
+ if wild_patterns. len ( ) as u64 == n {
1698
+ // convert a constant slice/array pattern to a list of patterns.
1699
+ match ( n , opt_ptr) {
1700
1700
( 0 , _) => Some ( Vec :: new ( ) ) ,
1701
1701
( _, Some ( ptr) ) => {
1702
1702
let alloc = cx. tcx . alloc_map . lock ( ) . unwrap_memory ( ptr. alloc_id ) ;
1703
- // FIXME: use `Allocation::read_bytes` once available
1704
- assert_eq ! ( ptr. offset. bytes( ) , 0 ) ;
1705
- Some ( alloc. bytes . iter ( ) . map ( |b| {
1706
- & * cx. pattern_arena . alloc ( Pattern {
1707
- ty : cx. tcx . types . u8 ,
1703
+ let layout = cx. tcx . layout_of ( cx. param_env . and ( ty) ) . ok ( ) ?;
1704
+ ( 0 ..n) . map ( |i| {
1705
+ let ptr = ptr. offset ( layout. size * i, & cx. tcx ) . ok ( ) ?;
1706
+ let scalar = alloc. read_scalar (
1707
+ & cx. tcx , ptr, layout. size ,
1708
+ ) . ok ( ) ?;
1709
+ let scalar = scalar. not_undef ( ) . ok ( ) ?;
1710
+ let value = ty:: Const :: from_scalar ( cx. tcx , scalar, ty) ;
1711
+ let pattern = Pattern {
1712
+ ty,
1708
1713
span : pat. span ,
1709
- kind : box PatternKind :: Constant {
1710
- value : ty:: Const :: from_bits (
1711
- cx. tcx ,
1712
- * b as u128 ,
1713
- ty:: ParamEnv :: empty ( ) . and ( cx. tcx . types . u8 ) )
1714
- } ,
1715
- } )
1716
- } ) . collect ( ) )
1714
+ kind : box PatternKind :: Constant { value } ,
1715
+ } ;
1716
+ Some ( & * cx. pattern_arena . alloc ( pattern) )
1717
+ } ) . collect ( )
1717
1718
} ,
1718
1719
( _, None ) => span_bug ! (
1719
1720
pat. span,
0 commit comments