@@ -330,47 +330,6 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
330330 } )
331331 }
332332
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-
374333 fn is_uninhabited ( & self , ty : Ty < ' tcx > ) -> bool {
375334 if self . tcx . features ( ) . exhaustive_patterns {
376335 self . tcx . is_ty_uninhabited_from ( self . module , ty)
@@ -1705,26 +1664,65 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
17051664 PatternKind :: Constant { value } => {
17061665 match * constructor {
17071666 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+ ) ,
17241723 }
17251724 } else {
1726- span_bug ! ( pat. span,
1727- "unexpected const-val {:?} with ctor {:?}" , value, constructor)
1725+ None
17281726 }
17291727 }
17301728 _ => {
0 commit comments