@@ -330,47 +330,6 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
330
330
} )
331
331
}
332
332
333
- // convert a byte-string pattern to a list of u8 patterns.
334
- fn lower_byte_str_pattern < ' p > ( & mut self , pat : & ' p Pattern < ' tcx > ) -> Vec < & ' p Pattern < ' tcx > >
335
- where ' a : ' p
336
- {
337
- let pattern_arena = & * self . pattern_arena ;
338
- let tcx = self . tcx ;
339
- self . byte_array_map . entry ( pat) . or_insert_with ( || {
340
- match pat. kind {
341
- box PatternKind :: Constant {
342
- value : const_val
343
- } => {
344
- if let Some ( ptr) = const_val. to_ptr ( ) {
345
- let is_array_ptr = const_val. ty
346
- . builtin_deref ( true )
347
- . and_then ( |t| t. ty . builtin_index ( ) )
348
- . map_or ( false , |t| t == tcx. types . u8 ) ;
349
- assert ! ( is_array_ptr) ;
350
- let alloc = tcx. alloc_map . lock ( ) . unwrap_memory ( ptr. alloc_id ) ;
351
- assert_eq ! ( ptr. offset. bytes( ) , 0 ) ;
352
- // FIXME: check length
353
- alloc. bytes . iter ( ) . map ( |b| {
354
- & * pattern_arena. alloc ( Pattern {
355
- ty : tcx. types . u8 ,
356
- span : pat. span ,
357
- kind : box PatternKind :: Constant {
358
- value : ty:: Const :: from_bits (
359
- tcx,
360
- * b as u128 ,
361
- ty:: ParamEnv :: empty ( ) . and ( tcx. types . u8 ) )
362
- }
363
- } )
364
- } ) . collect ( )
365
- } else {
366
- bug ! ( "not a byte str: {:?}" , const_val)
367
- }
368
- }
369
- _ => span_bug ! ( pat. span, "unexpected byte array pattern {:?}" , pat)
370
- }
371
- } ) . clone ( )
372
- }
373
-
374
333
fn is_uninhabited ( & self , ty : Ty < ' tcx > ) -> bool {
375
334
if self . tcx . features ( ) . exhaustive_patterns {
376
335
self . tcx . is_ty_uninhabited_from ( self . module , ty)
@@ -1705,26 +1664,65 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
1705
1664
PatternKind :: Constant { value } => {
1706
1665
match * constructor {
1707
1666
Slice ( ..) => {
1708
- if let Some ( ptr) = value. to_ptr ( ) {
1709
- let is_array_ptr = value. ty
1710
- . builtin_deref ( true )
1711
- . and_then ( |t| t. ty . builtin_index ( ) )
1712
- . map_or ( false , |t| t == cx. tcx . types . u8 ) ;
1713
- assert ! ( is_array_ptr) ;
1714
- let data_len = cx. tcx
1715
- . alloc_map
1716
- . lock ( )
1717
- . unwrap_memory ( ptr. alloc_id )
1718
- . bytes
1719
- . len ( ) ;
1720
- if wild_patterns. len ( ) == data_len {
1721
- Some ( cx. lower_byte_str_pattern ( pat) )
1722
- } else {
1723
- None
1667
+ // we extract an `Option` for the pointer because slices of zero elements don't
1668
+ // necessarily point to memory, they are usually just integers. The only time
1669
+ // they should be pointing to memory is when they are subslices of nonzero
1670
+ // 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
+ } ,
1676
+ ty:: TyKind :: Slice ( t) => {
1677
+ assert ! ( t == cx. tcx. types. u8 ) ;
1678
+ match value. val {
1679
+ ConstValue :: ScalarPair ( ptr, n) => (
1680
+ ptr. to_ptr ( ) . ok ( ) ,
1681
+ n. to_bits ( cx. tcx . data_layout . pointer_size ) . unwrap ( ) as u64
1682
+ ) ,
1683
+ _ => span_bug ! (
1684
+ pat. span,
1685
+ "slice pattern constant must be scalar pair but is {:?}" ,
1686
+ value,
1687
+ ) ,
1688
+ }
1689
+ } ,
1690
+ _ => span_bug ! (
1691
+ pat. span,
1692
+ "unexpected const-val {:?} with ctor {:?}" ,
1693
+ value,
1694
+ constructor,
1695
+ ) ,
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) {
1700
+ ( 0 , _) => Some ( Vec :: new ( ) ) ,
1701
+ ( _, Some ( ptr) ) => {
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 ,
1708
+ 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 ( ) )
1717
+ } ,
1718
+ ( _, None ) => span_bug ! (
1719
+ pat. span,
1720
+ "non zero length slice with const-val {:?}" ,
1721
+ value,
1722
+ ) ,
1724
1723
}
1725
1724
} else {
1726
- span_bug ! ( pat. span,
1727
- "unexpected const-val {:?} with ctor {:?}" , value, constructor)
1725
+ None
1728
1726
}
1729
1727
}
1730
1728
_ => {
0 commit comments