@@ -309,13 +309,15 @@ pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
309309 /// outside it's module and should not be matchable with an empty match
310310 /// statement.
311311 pub module : DefId ,
312+ param_env : ty:: ParamEnv < ' tcx > ,
312313 pub pattern_arena : & ' a TypedArena < Pattern < ' tcx > > ,
313314 pub byte_array_map : FxHashMap < * const Pattern < ' tcx > , Vec < & ' a Pattern < ' tcx > > > ,
314315}
315316
316317impl < ' a , ' tcx > MatchCheckCtxt < ' a , ' tcx > {
317318 pub fn create_and_enter < F , R > (
318319 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
320+ param_env : ty:: ParamEnv < ' tcx > ,
319321 module : DefId ,
320322 f : F ) -> R
321323 where F : for < ' b > FnOnce ( MatchCheckCtxt < ' b , ' tcx > ) -> R
@@ -324,6 +326,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
324326
325327 f ( MatchCheckCtxt {
326328 tcx,
329+ param_env,
327330 module,
328331 pattern_arena : & pattern_arena,
329332 byte_array_map : FxHashMap :: default ( ) ,
@@ -1668,17 +1671,14 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
16681671 // necessarily point to memory, they are usually just integers. The only time
16691672 // they should be pointing to memory is when they are subslices of nonzero
16701673 // 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) ,
16761676 ty:: TyKind :: Slice ( t) => {
1677- assert ! ( t == cx. tcx. types. u8 ) ;
16781677 match value. val {
16791678 ConstValue :: ScalarPair ( ptr, n) => (
16801679 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,
16821682 ) ,
16831683 _ => span_bug ! (
16841684 pat. span,
@@ -1694,26 +1694,27 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
16941694 constructor,
16951695 ) ,
16961696 } ;
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) {
17001700 ( 0 , _) => Some ( Vec :: new ( ) ) ,
17011701 ( _, Some ( ptr) ) => {
17021702 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,
17081713 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 ( )
17171718 } ,
17181719 ( _, None ) => span_bug ! (
17191720 pat. span,
0 commit comments