@@ -434,6 +434,13 @@ enum Constructor<'tcx> {
434434}
435435
436436impl < ' tcx > Constructor < ' tcx > {
437+ fn is_slice ( & self ) -> bool {
438+ match self {
439+ Slice { .. } => true ,
440+ _ => false ,
441+ }
442+ }
443+
437444 fn variant_index_for_adt < ' a > (
438445 & self ,
439446 cx : & MatchCheckCtxt < ' a , ' tcx > ,
@@ -1766,85 +1773,76 @@ fn specialize<'p, 'a: 'p, 'tcx>(
17661773 Some ( smallvec ! [ subpattern] )
17671774 }
17681775
1769- PatKind :: Constant { value } => {
1770- match * constructor {
1771- Slice ( ..) => {
1772- // we extract an `Option` for the pointer because slices of zero elements don't
1773- // necessarily point to memory, they are usually just integers. The only time
1774- // they should be pointing to memory is when they are subslices of nonzero
1775- // slices
1776- let ( alloc, offset, n, ty) = match value. ty . kind {
1777- ty:: Array ( t, n) => {
1778- match value. val {
1779- ConstValue :: ByRef { offset, alloc, .. } => (
1780- alloc,
1781- offset,
1782- n. eval_usize ( cx. tcx , cx. param_env ) ,
1783- t,
1784- ) ,
1785- _ => span_bug ! (
1786- pat. span,
1787- "array pattern is {:?}" , value,
1788- ) ,
1789- }
1790- } ,
1791- ty:: Slice ( t) => {
1792- match value. val {
1793- ConstValue :: Slice { data, start, end } => (
1794- data,
1795- Size :: from_bytes ( start as u64 ) ,
1796- ( end - start) as u64 ,
1797- t,
1798- ) ,
1799- ConstValue :: ByRef { .. } => {
1800- // FIXME(oli-obk): implement `deref` for `ConstValue`
1801- return None ;
1802- } ,
1803- _ => span_bug ! (
1804- pat. span,
1805- "slice pattern constant must be scalar pair but is {:?}" ,
1806- value,
1807- ) ,
1808- }
1776+ PatKind :: Constant { value } if constructor. is_slice ( ) => {
1777+ // We extract an `Option` for the pointer because slices of zero
1778+ // elements don't necessarily point to memory, they are usually
1779+ // just integers. The only time they should be pointing to memory
1780+ // is when they are subslices of nonzero slices.
1781+ let ( alloc, offset, n, ty) = match value. ty . kind {
1782+ ty:: Array ( t, n) => {
1783+ match value. val {
1784+ ConstValue :: ByRef { offset, alloc, .. } => (
1785+ alloc,
1786+ offset,
1787+ n. eval_usize ( cx. tcx , cx. param_env ) ,
1788+ t,
1789+ ) ,
1790+ _ => span_bug ! (
1791+ pat. span,
1792+ "array pattern is {:?}" , value,
1793+ ) ,
1794+ }
1795+ } ,
1796+ ty:: Slice ( t) => {
1797+ match value. val {
1798+ ConstValue :: Slice { data, start, end } => (
1799+ data,
1800+ Size :: from_bytes ( start as u64 ) ,
1801+ ( end - start) as u64 ,
1802+ t,
1803+ ) ,
1804+ ConstValue :: ByRef { .. } => {
1805+ // FIXME(oli-obk): implement `deref` for `ConstValue`
1806+ return None ;
18091807 } ,
18101808 _ => span_bug ! (
18111809 pat. span,
1812- "unexpected const-val {:?} with ctor {:?}" ,
1810+ "slice pattern constant must be scalar pair but is {:?}" ,
18131811 value,
1814- constructor,
18151812 ) ,
1816- } ;
1817- if wild_patterns. len ( ) as u64 == n {
1818- // convert a constant slice/array pattern to a list of patterns.
1819- let layout = cx. tcx . layout_of ( cx. param_env . and ( ty) ) . ok ( ) ?;
1820- let ptr = Pointer :: new ( AllocId ( 0 ) , offset) ;
1821- ( 0 ..n) . map ( |i| {
1822- let ptr = ptr. offset ( layout. size * i, & cx. tcx ) . ok ( ) ?;
1823- let scalar = alloc. read_scalar (
1824- & cx. tcx , ptr, layout. size ,
1825- ) . ok ( ) ?;
1826- let scalar = scalar. not_undef ( ) . ok ( ) ?;
1827- let value = ty:: Const :: from_scalar ( cx. tcx , scalar, ty) ;
1828- let pattern = Pat {
1829- ty,
1830- span : pat. span ,
1831- kind : box PatKind :: Constant { value } ,
1832- } ;
1833- Some ( & * cx. pattern_arena . alloc ( pattern) )
1834- } ) . collect ( )
1835- } else {
1836- None
18371813 }
1838- }
1839- _ => {
1840- // If the constructor is a:
1841- // Single value: add a row if the constructor equals the pattern.
1842- // Range: add a row if the constructor contains the pattern.
1843- constructor_intersects_pattern ( cx. tcx , cx. param_env , constructor, pat)
1844- }
1814+ } ,
1815+ _ => span_bug ! (
1816+ pat. span,
1817+ "unexpected const-val {:?} with ctor {:?}" ,
1818+ value,
1819+ constructor,
1820+ ) ,
1821+ } ;
1822+ if wild_patterns. len ( ) as u64 == n {
1823+ // convert a constant slice/array pattern to a list of patterns.
1824+ let layout = cx. tcx . layout_of ( cx. param_env . and ( ty) ) . ok ( ) ?;
1825+ let ptr = Pointer :: new ( AllocId ( 0 ) , offset) ;
1826+ ( 0 ..n) . map ( |i| {
1827+ let ptr = ptr. offset ( layout. size * i, & cx. tcx ) . ok ( ) ?;
1828+ let scalar = alloc. read_scalar (
1829+ & cx. tcx , ptr, layout. size ,
1830+ ) . ok ( ) ?;
1831+ let scalar = scalar. not_undef ( ) . ok ( ) ?;
1832+ let value = ty:: Const :: from_scalar ( cx. tcx , scalar, ty) ;
1833+ let pattern = Pat {
1834+ ty,
1835+ span : pat. span ,
1836+ kind : box PatKind :: Constant { value } ,
1837+ } ;
1838+ Some ( & * cx. pattern_arena . alloc ( pattern) )
1839+ } ) . collect ( )
1840+ } else {
1841+ None
18451842 }
18461843 }
18471844
1845+ PatKind :: Constant { .. } |
18481846 PatKind :: Range { .. } => {
18491847 // If the constructor is a:
18501848 // Single value: add a row if the pattern contains the constructor.
0 commit comments