|
1 | 1 | use std::cell::Cell;
|
2 | 2 | use std::cmp::Ordering::{self, Equal, Greater, Less};
|
| 3 | +use std::convert::identity; |
3 | 4 | use std::mem;
|
4 | 5 | use std::panic;
|
5 | 6 | use std::rc::Rc;
|
@@ -1778,3 +1779,122 @@ fn repeat_generic_slice() {
|
1778 | 1779 | assert_eq!([1, 2, 3, 4].repeat(1), vec![1, 2, 3, 4]);
|
1779 | 1780 | assert_eq!([1, 2, 3, 4].repeat(3), vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]);
|
1780 | 1781 | }
|
| 1782 | + |
| 1783 | +#[test] |
| 1784 | +#[allow(unreachable_patterns)] |
| 1785 | +fn subslice_patterns() { |
| 1786 | + // This test comprehensively checks the passing static and dynamic semantics |
| 1787 | + // of subslice patterns `..`, `x @ ..`, `ref x @ ..`, and `ref mut @ ..` |
| 1788 | + // in slice patterns `[$($pat), $(,)?]` . |
| 1789 | + |
| 1790 | + #[derive(PartialEq, Debug, Clone)] |
| 1791 | + struct N(u8); |
| 1792 | + |
| 1793 | + macro_rules! n { |
| 1794 | + ($($e:expr),* $(,)?) => { |
| 1795 | + [$(N($e)),*] |
| 1796 | + } |
| 1797 | + } |
| 1798 | + |
| 1799 | + macro_rules! c { |
| 1800 | + ($inp:expr, $typ:ty, $out:expr $(,)?) => { |
| 1801 | + assert_eq!($out, identity::<$typ>($inp)); |
| 1802 | + }; |
| 1803 | + } |
| 1804 | + |
| 1805 | + macro_rules! m { |
| 1806 | + ($e:expr, $p:pat => $b:expr) => { |
| 1807 | + match $e { |
| 1808 | + $p => $b, |
| 1809 | + _ => panic!(), |
| 1810 | + } |
| 1811 | + }; |
| 1812 | + } |
| 1813 | + |
| 1814 | + // == Slices == |
| 1815 | + |
| 1816 | + // Matching slices using `ref` patterns: |
| 1817 | + let mut v = vec![N(0), N(1), N(2), N(3), N(4)]; |
| 1818 | + let mut vc = (0..=4).collect::<Vec<u8>>(); |
| 1819 | + |
| 1820 | + let [..] = v[..]; // Always matches. |
| 1821 | + m!(v[..], [N(0), ref sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); |
| 1822 | + m!(v[..], [N(0), ref sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); |
| 1823 | + m!(v[..], [ref sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); |
| 1824 | + m!(v[..], [ref sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); |
| 1825 | + m!(v[..], [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N], &n![] as &[N])); |
| 1826 | + m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); |
| 1827 | + |
| 1828 | + // Matching slices using `ref mut` patterns: |
| 1829 | + let [..] = v[..]; // Always matches. |
| 1830 | + m!(v[..], [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); |
| 1831 | + m!(v[..], [N(0), ref mut sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); |
| 1832 | + m!(v[..], [ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); |
| 1833 | + m!(v[..], [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); |
| 1834 | + m!(v[..], [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); |
| 1835 | + m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); |
| 1836 | + |
| 1837 | + // Matching slices using default binding modes (&): |
| 1838 | + let [..] = &v[..]; // Always matches. |
| 1839 | + m!(&v[..], [N(0), sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); |
| 1840 | + m!(&v[..], [N(0), sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); |
| 1841 | + m!(&v[..], [sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); |
| 1842 | + m!(&v[..], [sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); |
| 1843 | + m!(&v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &[N], &n![] as &[N])); |
| 1844 | + m!(&vc[..], [x, .., y] => c!((x, y), (&u8, &u8), (&0, &4))); |
| 1845 | + |
| 1846 | + // Matching slices using default binding modes (&mut): |
| 1847 | + let [..] = &mut v[..]; // Always matches. |
| 1848 | + m!(&mut v[..], [N(0), sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); |
| 1849 | + m!(&mut v[..], [N(0), sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); |
| 1850 | + m!(&mut v[..], [sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); |
| 1851 | + m!(&mut v[..], [sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); |
| 1852 | + m!(&mut v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); |
| 1853 | + m!(&mut vc[..], [x, .., y] => c!((x, y), (&mut u8, &mut u8), (&mut 0, &mut 4))); |
| 1854 | + |
| 1855 | + // == Arrays == |
| 1856 | + let mut v = n![0, 1, 2, 3, 4]; |
| 1857 | + let vc = [0, 1, 2, 3, 4]; |
| 1858 | + |
| 1859 | + // Matching arrays by value: |
| 1860 | + m!(v.clone(), [N(0), sub @ .., N(4)] => c!(sub, [N; 3], n![1, 2, 3])); |
| 1861 | + m!(v.clone(), [N(0), sub @ ..] => c!(sub, [N; 4], n![1, 2, 3, 4])); |
| 1862 | + m!(v.clone(), [sub @ .., N(4)] => c!(sub, [N; 4], n![0, 1, 2, 3])); |
| 1863 | + m!(v.clone(), [sub @ .., _, _, _, _, _] => c!(sub, [N; 0], n![] as [N; 0])); |
| 1864 | + m!(v.clone(), [_, _, _, _, _, sub @ ..] => c!(sub, [N; 0], n![] as [N; 0])); |
| 1865 | + m!(v.clone(), [x, .., y] => c!((x, y), (N, N), (N(0), N(4)))); |
| 1866 | + m!(v.clone(), [..] => ()); |
| 1867 | + |
| 1868 | + // Matching arrays by ref patterns: |
| 1869 | + m!(v, [N(0), ref sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); |
| 1870 | + m!(v, [N(0), ref sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); |
| 1871 | + m!(v, [ref sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); |
| 1872 | + m!(v, [ref sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); |
| 1873 | + m!(v, [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); |
| 1874 | + m!(vc, [x, .., y] => c!((x, y), (u8, u8), (0, 4))); |
| 1875 | + |
| 1876 | + // Matching arrays by ref mut patterns: |
| 1877 | + m!(v, [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); |
| 1878 | + m!(v, [N(0), ref mut sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); |
| 1879 | + m!(v, [ref mut sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); |
| 1880 | + m!(v, [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); |
| 1881 | + m!(v, [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); |
| 1882 | + |
| 1883 | + // Matching arrays by default binding modes (&): |
| 1884 | + m!(&v, [N(0), sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); |
| 1885 | + m!(&v, [N(0), sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); |
| 1886 | + m!(&v, [sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); |
| 1887 | + m!(&v, [sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); |
| 1888 | + m!(&v, [_, _, _, _, _, sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); |
| 1889 | + m!(&v, [..] => ()); |
| 1890 | + m!(&v, [x, .., y] => c!((x, y), (&N, &N), (&N(0), &N(4)))); |
| 1891 | + |
| 1892 | + // Matching arrays by default binding modes (&mut): |
| 1893 | + m!(&mut v, [N(0), sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); |
| 1894 | + m!(&mut v, [N(0), sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); |
| 1895 | + m!(&mut v, [sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); |
| 1896 | + m!(&mut v, [sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); |
| 1897 | + m!(&mut v, [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); |
| 1898 | + m!(&mut v, [..] => ()); |
| 1899 | + m!(&mut v, [x, .., y] => c!((x, y), (&mut N, &mut N), (&mut N(0), &mut N(4)))); |
| 1900 | +} |
0 commit comments