@@ -434,6 +434,13 @@ enum Constructor<'tcx> {
434
434
}
435
435
436
436
impl < ' tcx > Constructor < ' tcx > {
437
+ fn is_slice ( & self ) -> bool {
438
+ match self {
439
+ Slice { .. } => true ,
440
+ _ => false ,
441
+ }
442
+ }
443
+
437
444
fn variant_index_for_adt < ' a > (
438
445
& self ,
439
446
cx : & MatchCheckCtxt < ' a , ' tcx > ,
@@ -1766,85 +1773,76 @@ fn specialize<'p, 'a: 'p, 'tcx>(
1766
1773
Some ( smallvec ! [ subpattern] )
1767
1774
}
1768
1775
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 ;
1809
1807
} ,
1810
1808
_ => span_bug ! (
1811
1809
pat. span,
1812
- "unexpected const-val {:?} with ctor {:?}" ,
1810
+ "slice pattern constant must be scalar pair but is {:?}" ,
1813
1811
value,
1814
- constructor,
1815
1812
) ,
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
1837
1813
}
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
1845
1842
}
1846
1843
}
1847
1844
1845
+ PatKind :: Constant { .. } |
1848
1846
PatKind :: Range { .. } => {
1849
1847
// If the constructor is a:
1850
1848
// Single value: add a row if the pattern contains the constructor.
0 commit comments