diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs index 1f561bebd908b..a4f0fb415fb3c 100644 --- a/library/alloc/tests/slice.rs +++ b/library/alloc/tests/slice.rs @@ -1,5 +1,6 @@ use std::cell::Cell; use std::cmp::Ordering::{self, Equal, Greater, Less}; +use std::convert::identity; use std::mem; use std::panic; use std::rc::Rc; @@ -1778,3 +1779,122 @@ fn repeat_generic_slice() { assert_eq!([1, 2, 3, 4].repeat(1), vec![1, 2, 3, 4]); assert_eq!([1, 2, 3, 4].repeat(3), vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]); } + +#[test] +#[allow(unreachable_patterns)] +fn subslice_patterns() { + // This test comprehensively checks the passing static and dynamic semantics + // of subslice patterns `..`, `x @ ..`, `ref x @ ..`, and `ref mut @ ..` + // in slice patterns `[$($pat), $(,)?]` . + + #[derive(PartialEq, Debug, Clone)] + struct N(u8); + + macro_rules! n { + ($($e:expr),* $(,)?) => { + [$(N($e)),*] + } + } + + macro_rules! c { + ($inp:expr, $typ:ty, $out:expr $(,)?) => { + assert_eq!($out, identity::<$typ>($inp)); + }; + } + + macro_rules! m { + ($e:expr, $p:pat => $b:expr) => { + match $e { + $p => $b, + _ => panic!(), + } + }; + } + + // == Slices == + + // Matching slices using `ref` patterns: + let mut v = vec![N(0), N(1), N(2), N(3), N(4)]; + let mut vc = (0..=4).collect::>(); + + let [..] = v[..]; // Always matches. + m!(v[..], [N(0), ref sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); + m!(v[..], [N(0), ref sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); + m!(v[..], [ref sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); + m!(v[..], [ref sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); + m!(v[..], [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N], &n![] as &[N])); + m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); + + // Matching slices using `ref mut` patterns: + let [..] = v[..]; // Always matches. + m!(v[..], [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); + m!(v[..], [N(0), ref mut sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); + m!(v[..], [ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); + m!(v[..], [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); + m!(v[..], [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); + m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); + + // Matching slices using default binding modes (&): + let [..] = &v[..]; // Always matches. + m!(&v[..], [N(0), sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); + m!(&v[..], [N(0), sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); + m!(&v[..], [sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); + m!(&v[..], [sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); + m!(&v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &[N], &n![] as &[N])); + m!(&vc[..], [x, .., y] => c!((x, y), (&u8, &u8), (&0, &4))); + + // Matching slices using default binding modes (&mut): + let [..] = &mut v[..]; // Always matches. + m!(&mut v[..], [N(0), sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); + m!(&mut v[..], [N(0), sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); + m!(&mut v[..], [sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); + m!(&mut v[..], [sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); + m!(&mut v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); + m!(&mut vc[..], [x, .., y] => c!((x, y), (&mut u8, &mut u8), (&mut 0, &mut 4))); + + // == Arrays == + let mut v = n![0, 1, 2, 3, 4]; + let vc = [0, 1, 2, 3, 4]; + + // Matching arrays by value: + m!(v.clone(), [N(0), sub @ .., N(4)] => c!(sub, [N; 3], n![1, 2, 3])); + m!(v.clone(), [N(0), sub @ ..] => c!(sub, [N; 4], n![1, 2, 3, 4])); + m!(v.clone(), [sub @ .., N(4)] => c!(sub, [N; 4], n![0, 1, 2, 3])); + m!(v.clone(), [sub @ .., _, _, _, _, _] => c!(sub, [N; 0], n![] as [N; 0])); + m!(v.clone(), [_, _, _, _, _, sub @ ..] => c!(sub, [N; 0], n![] as [N; 0])); + m!(v.clone(), [x, .., y] => c!((x, y), (N, N), (N(0), N(4)))); + m!(v.clone(), [..] => ()); + + // Matching arrays by ref patterns: + m!(v, [N(0), ref sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); + m!(v, [N(0), ref sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); + m!(v, [ref sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); + m!(v, [ref sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); + m!(v, [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); + m!(vc, [x, .., y] => c!((x, y), (u8, u8), (0, 4))); + + // Matching arrays by ref mut patterns: + m!(v, [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); + m!(v, [N(0), ref mut sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); + m!(v, [ref mut sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); + m!(v, [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); + m!(v, [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); + + // Matching arrays by default binding modes (&): + m!(&v, [N(0), sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); + m!(&v, [N(0), sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); + m!(&v, [sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); + m!(&v, [sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); + m!(&v, [_, _, _, _, _, sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); + m!(&v, [..] => ()); + m!(&v, [x, .., y] => c!((x, y), (&N, &N), (&N(0), &N(4)))); + + // Matching arrays by default binding modes (&mut): + m!(&mut v, [N(0), sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); + m!(&mut v, [N(0), sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); + m!(&mut v, [sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); + m!(&mut v, [sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); + m!(&mut v, [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); + m!(&mut v, [..] => ()); + m!(&mut v, [x, .., y] => c!((x, y), (&mut N, &mut N), (&mut N(0), &mut N(4)))); +} diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 771a293b8e5d4..47ebe56f9fd3b 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -3,7 +3,7 @@ use std::cell::Cell; use std::collections::TryReserveError::*; use std::fmt::Debug; use std::iter::InPlaceIterable; -use std::mem::size_of; +use std::mem::{size_of, swap}; use std::ops::Bound::*; use std::panic::{catch_unwind, AssertUnwindSafe}; use std::rc::Rc; @@ -1912,3 +1912,45 @@ fn test_vec_cycle_wrapped() { c3.refs.v[0].set(Some(&c1)); c3.refs.v[1].set(Some(&c2)); } + +#[test] +fn test_zero_sized_vec_push() { + const N: usize = 8; + + for len in 0..N { + let mut tester = Vec::with_capacity(len); + assert_eq!(tester.len(), 0); + assert!(tester.capacity() >= len); + for _ in 0..len { + tester.push(()); + } + assert_eq!(tester.len(), len); + assert_eq!(tester.iter().count(), len); + tester.clear(); + } +} + +#[test] +fn test_vec_macro_repeat() { + assert_eq!(vec![1; 3], vec![1, 1, 1]); + assert_eq!(vec![1; 2], vec![1, 1]); + assert_eq!(vec![1; 1], vec![1]); + assert_eq!(vec![1; 0], vec![]); + + // from_elem syntax (see RFC 832) + let el = Box::new(1); + let n = 3; + assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]); +} + +#[test] +fn test_vec_swap() { + let mut a: Vec = vec![0, 1, 2, 3, 4, 5, 6]; + a.swap(2, 4); + assert_eq!(a[2], 4); + assert_eq!(a[4], 2); + let mut n = 42; + swap(&mut n, &mut a[0]); + assert_eq!(a[0], 42); + assert_eq!(n, 0); +} diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index 05cb3a2c03d79..705f0d62fbb7a 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -1698,3 +1698,33 @@ fn test_binary_search_by_key() { assert_eq!(deque.binary_search_by_key(&3, |&(v,)| v), Ok(2)); assert_eq!(deque.binary_search_by_key(&4, |&(v,)| v), Err(3)); } + +#[test] +fn test_zero_sized_push() { + const N: usize = 8; + + // Zero sized type + struct Zst; + + // Test that for all possible sequences of push_front / push_back, + // we end up with a deque of the correct size + + for len in 0..N { + let mut tester = VecDeque::with_capacity(len); + assert_eq!(tester.len(), 0); + assert!(tester.capacity() >= len); + for case in 0..(1 << len) { + assert_eq!(tester.len(), 0); + for bit in 0..len { + if case & (1 << bit) != 0 { + tester.push_front(Zst); + } else { + tester.push_back(Zst); + } + } + assert_eq!(tester.len(), len); + assert_eq!(tester.iter().count(), len); + tester.clear(); + } + } +} diff --git a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs b/src/test/ui/array-slice-vec/subslice-patterns-pass.rs deleted file mode 100644 index e05790911f52d..0000000000000 --- a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs +++ /dev/null @@ -1,126 +0,0 @@ -// This test comprehensively checks the passing static and dynamic semantics -// of subslice patterns `..`, `x @ ..`, `ref x @ ..`, and `ref mut @ ..` -// in slice patterns `[$($pat), $(,)?]` . - -// run-pass - -#![allow(unreachable_patterns)] - -use std::convert::identity; - -#[derive(PartialEq, Debug, Clone)] -struct N(u8); - -macro_rules! n { - ($($e:expr),* $(,)?) => { - [$(N($e)),*] - } -} - -macro_rules! c { - ($inp:expr, $typ:ty, $out:expr $(,)?) => { - assert_eq!($out, identity::<$typ>($inp)); - } -} - -macro_rules! m { - ($e:expr, $p:pat => $b:expr) => { - match $e { - $p => $b, - _ => panic!(), - } - } -} - -fn main() { - slices(); - arrays(); -} - -fn slices() { - // Matching slices using `ref` patterns: - let mut v = vec![N(0), N(1), N(2), N(3), N(4)]; - let mut vc = (0..=4).collect::>(); - - let [..] = v[..]; // Always matches. - m!(v[..], [N(0), ref sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); - m!(v[..], [N(0), ref sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); - m!(v[..], [ref sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); - m!(v[..], [ref sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); - m!(v[..], [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N], &n![] as &[N])); - m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); - - // Matching slices using `ref mut` patterns: - let [..] = v[..]; // Always matches. - m!(v[..], [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); - m!(v[..], [N(0), ref mut sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); - m!(v[..], [ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); - m!(v[..], [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); - m!(v[..], [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); - m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); - - // Matching slices using default binding modes (&): - let [..] = &v[..]; // Always matches. - m!(&v[..], [N(0), sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); - m!(&v[..], [N(0), sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); - m!(&v[..], [sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); - m!(&v[..], [sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); - m!(&v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &[N], &n![] as &[N])); - m!(&vc[..], [x, .., y] => c!((x, y), (&u8, &u8), (&0, &4))); - - // Matching slices using default binding modes (&mut): - let [..] = &mut v[..]; // Always matches. - m!(&mut v[..], [N(0), sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); - m!(&mut v[..], [N(0), sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); - m!(&mut v[..], [sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); - m!(&mut v[..], [sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); - m!(&mut v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); - m!(&mut vc[..], [x, .., y] => c!((x, y), (&mut u8, &mut u8), (&mut 0, &mut 4))); -} - -fn arrays() { - let mut v = n![0, 1, 2, 3, 4]; - let vc = [0, 1, 2, 3, 4]; - - // Matching arrays by value: - m!(v.clone(), [N(0), sub @ .., N(4)] => c!(sub, [N; 3], n![1, 2, 3])); - m!(v.clone(), [N(0), sub @ ..] => c!(sub, [N; 4], n![1, 2, 3, 4])); - m!(v.clone(), [sub @ .., N(4)] => c!(sub, [N; 4], n![0, 1, 2, 3])); - m!(v.clone(), [sub @ .., _, _, _, _, _] => c!(sub, [N; 0], n![] as [N; 0])); - m!(v.clone(), [_, _, _, _, _, sub @ ..] => c!(sub, [N; 0], n![] as [N; 0])); - m!(v.clone(), [x, .., y] => c!((x, y), (N, N), (N(0), N(4)))); - m!(v.clone(), [..] => ()); - - // Matching arrays by ref patterns: - m!(v, [N(0), ref sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); - m!(v, [N(0), ref sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); - m!(v, [ref sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); - m!(v, [ref sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); - m!(v, [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); - m!(vc, [x, .., y] => c!((x, y), (u8, u8), (0, 4))); - - // Matching arrays by ref mut patterns: - m!(v, [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); - m!(v, [N(0), ref mut sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); - m!(v, [ref mut sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); - m!(v, [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); - m!(v, [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); - - // Matching arrays by default binding modes (&): - m!(&v, [N(0), sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); - m!(&v, [N(0), sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); - m!(&v, [sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); - m!(&v, [sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); - m!(&v, [_, _, _, _, _, sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); - m!(&v, [..] => ()); - m!(&v, [x, .., y] => c!((x, y), (&N, &N), (&N(0), &N(4)))); - - // Matching arrays by default binding modes (&mut): - m!(&mut v, [N(0), sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); - m!(&mut v, [N(0), sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); - m!(&mut v, [sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); - m!(&mut v, [sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); - m!(&mut v, [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); - m!(&mut v, [..] => ()); - m!(&mut v, [x, .., y] => c!((x, y), (&mut N, &mut N), (&mut N(0), &mut N(4)))); -} diff --git a/src/test/ui/array-slice-vec/vec-macro-repeat.rs b/src/test/ui/array-slice-vec/vec-macro-repeat.rs deleted file mode 100644 index 7be8dadbe170e..0000000000000 --- a/src/test/ui/array-slice-vec/vec-macro-repeat.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - - - -pub fn main() { - assert_eq!(vec![1; 3], vec![1, 1, 1]); - assert_eq!(vec![1; 2], vec![1, 1]); - assert_eq!(vec![1; 1], vec![1]); - assert_eq!(vec![1; 0], vec![]); - - // from_elem syntax (see RFC 832) - let el = Box::new(1); - let n = 3; - assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]); -} diff --git a/src/test/ui/swap-2.rs b/src/test/ui/swap-2.rs deleted file mode 100644 index c8f298ec0e5cb..0000000000000 --- a/src/test/ui/swap-2.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass - -use std::mem::swap; - -pub fn main() { - let mut a: Vec = vec![0, 1, 2, 3, 4, 5, 6]; - a.swap(2, 4); - assert_eq!(a[2], 4); - assert_eq!(a[4], 2); - let mut n = 42; - swap(&mut n, &mut a[0]); - assert_eq!(a[0], 42); - assert_eq!(n, 0); -} diff --git a/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs b/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs deleted file mode 100644 index c541208703b6b..0000000000000 --- a/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs +++ /dev/null @@ -1,32 +0,0 @@ -// run-pass -use std::collections::VecDeque; -use std::iter::Iterator; - -fn main() { - const N: usize = 8; - - // Zero sized type - struct Zst; - - // Test that for all possible sequences of push_front / push_back, - // we end up with a deque of the correct size - - for len in 0..N { - let mut tester = VecDeque::with_capacity(len); - assert_eq!(tester.len(), 0); - assert!(tester.capacity() >= len); - for case in 0..(1 << len) { - assert_eq!(tester.len(), 0); - for bit in 0..len { - if case & (1 << bit) != 0 { - tester.push_front(Zst); - } else { - tester.push_back(Zst); - } - } - assert_eq!(tester.len(), len); - assert_eq!(tester.iter().count(), len); - tester.clear(); - } - } -} diff --git a/src/test/ui/zero-sized/zero-sized-vec-push.rs b/src/test/ui/zero-sized/zero-sized-vec-push.rs deleted file mode 100644 index 9e9fbc972d5c1..0000000000000 --- a/src/test/ui/zero-sized/zero-sized-vec-push.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass -#![allow(unused_variables)] -use std::iter::Iterator; -use std::vec::Vec; - -fn main() { - const N: usize = 8; - - for len in 0..N { - let mut tester = Vec::with_capacity(len); - assert_eq!(tester.len(), 0); - assert!(tester.capacity() >= len); - for bit in 0..len { - tester.push(()); - } - assert_eq!(tester.len(), len); - assert_eq!(tester.iter().count(), len); - tester.clear(); - } -}