summaryrefslogtreecommitdiffstats
path: root/src/test/ui/array-slice-vec
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/ui/array-slice-vec/array-break-length.rs9
-rw-r--r--src/test/ui/array-slice-vec/array-break-length.stderr15
-rw-r--r--src/test/ui/array-slice-vec/array-not-vector.rs12
-rw-r--r--src/test/ui/array-slice-vec/array-not-vector.stderr22
-rw-r--r--src/test/ui/array-slice-vec/array_const_index-0.rs9
-rw-r--r--src/test/ui/array-slice-vec/array_const_index-0.stderr23
-rw-r--r--src/test/ui/array-slice-vec/array_const_index-1.rs9
-rw-r--r--src/test/ui/array-slice-vec/array_const_index-1.stderr23
-rw-r--r--src/test/ui/array-slice-vec/array_const_index-2.rs12
-rw-r--r--src/test/ui/array-slice-vec/bounds-check-no-overflow.rs10
-rw-r--r--src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs53
-rw-r--r--src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs53
-rw-r--r--src/test/ui/array-slice-vec/byte-literals.rs67
-rw-r--r--src/test/ui/array-slice-vec/cast-in-array-size.rs14
-rw-r--r--src/test/ui/array-slice-vec/check-static-mut-slices.rs15
-rw-r--r--src/test/ui/array-slice-vec/check-static-slice.rs36
-rw-r--r--src/test/ui/array-slice-vec/copy-out-of-array-1.rs19
-rw-r--r--src/test/ui/array-slice-vec/destructure-array-1.rs27
-rw-r--r--src/test/ui/array-slice-vec/dst-raw-slice.rs13
-rw-r--r--src/test/ui/array-slice-vec/empty-mutable-vec.rs8
-rw-r--r--src/test/ui/array-slice-vec/estr-slice.rs50
-rw-r--r--src/test/ui/array-slice-vec/evec-slice.rs47
-rw-r--r--src/test/ui/array-slice-vec/fixed_length_copy.rs9
-rw-r--r--src/test/ui/array-slice-vec/huge-largest-array.rs14
-rw-r--r--src/test/ui/array-slice-vec/infer_array_len.rs21
-rw-r--r--src/test/ui/array-slice-vec/infer_array_len.stderr14
-rw-r--r--src/test/ui/array-slice-vec/issue-15730.rs9
-rw-r--r--src/test/ui/array-slice-vec/issue-18425.rs9
-rw-r--r--src/test/ui/array-slice-vec/issue-69103-extra-binding-subslice.rs18
-rw-r--r--src/test/ui/array-slice-vec/issue-69103-extra-binding-subslice.stderr26
-rw-r--r--src/test/ui/array-slice-vec/ivec-pass-by-value.rs4
-rw-r--r--src/test/ui/array-slice-vec/match_arr_unknown_len.rs8
-rw-r--r--src/test/ui/array-slice-vec/match_arr_unknown_len.stderr12
-rw-r--r--src/test/ui/array-slice-vec/mut-vstore-expr.rs6
-rw-r--r--src/test/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs19
-rw-r--r--src/test/ui/array-slice-vec/mutable-alias-vec.rs15
-rw-r--r--src/test/ui/array-slice-vec/nested-vec-1.rs8
-rw-r--r--src/test/ui/array-slice-vec/nested-vec-2.rs15
-rw-r--r--src/test/ui/array-slice-vec/nested-vec-3.rs60
-rw-r--r--src/test/ui/array-slice-vec/new-style-fixed-length-vec.rs7
-rw-r--r--src/test/ui/array-slice-vec/rcvr-borrowed-to-slice.rs33
-rw-r--r--src/test/ui/array-slice-vec/repeat_empty_ok.rs15
-rw-r--r--src/test/ui/array-slice-vec/repeat_empty_ok.stderr27
-rw-r--r--src/test/ui/array-slice-vec/repeated-vector-syntax.rs13
-rw-r--r--src/test/ui/array-slice-vec/show-boxed-slice.rs8
-rw-r--r--src/test/ui/array-slice-vec/slice-2.rs11
-rw-r--r--src/test/ui/array-slice-vec/slice-2.stderr27
-rw-r--r--src/test/ui/array-slice-vec/slice-mut-2.rs8
-rw-r--r--src/test/ui/array-slice-vec/slice-mut-2.stderr12
-rw-r--r--src/test/ui/array-slice-vec/slice-mut.rs12
-rw-r--r--src/test/ui/array-slice-vec/slice-mut.stderr14
-rw-r--r--src/test/ui/array-slice-vec/slice-of-zero-size-elements.rs53
-rw-r--r--src/test/ui/array-slice-vec/slice-panic-1.rs27
-rw-r--r--src/test/ui/array-slice-vec/slice-panic-2.rs31
-rw-r--r--src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs36
-rw-r--r--src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr34
-rw-r--r--src/test/ui/array-slice-vec/slice-to-vec-comparison.rs6
-rw-r--r--src/test/ui/array-slice-vec/slice-to-vec-comparison.stderr12
-rw-r--r--src/test/ui/array-slice-vec/slice.rs81
-rw-r--r--src/test/ui/array-slice-vec/slice_binary_search.rs22
-rw-r--r--src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs11
-rw-r--r--src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr24
-rw-r--r--src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs96
-rw-r--r--src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs95
-rw-r--r--src/test/ui/array-slice-vec/variance-vec-covariant.rs20
-rw-r--r--src/test/ui/array-slice-vec/vec-dst.rs24
-rw-r--r--src/test/ui/array-slice-vec/vec-fixed-length.rs24
-rw-r--r--src/test/ui/array-slice-vec/vec-late-init.rs9
-rw-r--r--src/test/ui/array-slice-vec/vec-macro-no-std.rs27
-rw-r--r--src/test/ui/array-slice-vec/vec-macro-rvalue-scope.rs11
-rw-r--r--src/test/ui/array-slice-vec/vec-macro-with-brackets.rs16
-rw-r--r--src/test/ui/array-slice-vec/vec-macro-with-comma-only.rs3
-rw-r--r--src/test/ui/array-slice-vec/vec-macro-with-comma-only.stderr8
-rw-r--r--src/test/ui/array-slice-vec/vec-macro-with-trailing-comma.rs8
-rw-r--r--src/test/ui/array-slice-vec/vec-matching-autoslice.rs23
-rw-r--r--src/test/ui/array-slice-vec/vec-matching-fixed.rs30
-rw-r--r--src/test/ui/array-slice-vec/vec-matching-fold.rs46
-rw-r--r--src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs15
-rw-r--r--src/test/ui/array-slice-vec/vec-matching.rs142
-rw-r--r--src/test/ui/array-slice-vec/vec-mut-iter-borrow.rs7
-rw-r--r--src/test/ui/array-slice-vec/vec-mut-iter-borrow.stderr14
-rw-r--r--src/test/ui/array-slice-vec/vec-overrun.rs12
-rw-r--r--src/test/ui/array-slice-vec/vec-repeat-with-cast.rs5
-rw-r--r--src/test/ui/array-slice-vec/vec-res-add.rs19
-rw-r--r--src/test/ui/array-slice-vec/vec-res-add.stderr11
-rw-r--r--src/test/ui/array-slice-vec/vec-tail-matching.rs34
-rw-r--r--src/test/ui/array-slice-vec/vector-cast-weirdness.rs34
-rw-r--r--src/test/ui/array-slice-vec/vector-cast-weirdness.stderr21
-rw-r--r--src/test/ui/array-slice-vec/vector-no-ann-2.rs7
-rw-r--r--src/test/ui/array-slice-vec/vector-no-ann.rs4
-rw-r--r--src/test/ui/array-slice-vec/vector-no-ann.stderr14
91 files changed, 2116 insertions, 0 deletions
diff --git a/src/test/ui/array-slice-vec/array-break-length.rs b/src/test/ui/array-slice-vec/array-break-length.rs
new file mode 100644
index 000000000..60589f7c2
--- /dev/null
+++ b/src/test/ui/array-slice-vec/array-break-length.rs
@@ -0,0 +1,9 @@
+fn main() {
+ loop {
+ |_: [_; break]| {} //~ ERROR: `break` outside of a loop
+ }
+
+ loop {
+ |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop
+ }
+}
diff --git a/src/test/ui/array-slice-vec/array-break-length.stderr b/src/test/ui/array-slice-vec/array-break-length.stderr
new file mode 100644
index 000000000..93f1c238b
--- /dev/null
+++ b/src/test/ui/array-slice-vec/array-break-length.stderr
@@ -0,0 +1,15 @@
+error[E0268]: `break` outside of a loop
+ --> $DIR/array-break-length.rs:3:17
+ |
+LL | |_: [_; break]| {}
+ | ^^^^^ cannot `break` outside of a loop
+
+error[E0268]: `continue` outside of a loop
+ --> $DIR/array-break-length.rs:7:17
+ |
+LL | |_: [_; continue]| {}
+ | ^^^^^^^^ cannot `continue` outside of a loop
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0268`.
diff --git a/src/test/ui/array-slice-vec/array-not-vector.rs b/src/test/ui/array-slice-vec/array-not-vector.rs
new file mode 100644
index 000000000..5e46f015b
--- /dev/null
+++ b/src/test/ui/array-slice-vec/array-not-vector.rs
@@ -0,0 +1,12 @@
+fn main() {
+ let _x: i32 = [1, 2, 3];
+ //~^ ERROR mismatched types
+ //~| expected `i32`, found array
+
+ let x: &[i32] = &[1, 2, 3];
+ let _y: &i32 = x;
+ //~^ ERROR mismatched types
+ //~| expected reference `&i32`
+ //~| found reference `&[i32]`
+ //~| expected `i32`, found slice
+}
diff --git a/src/test/ui/array-slice-vec/array-not-vector.stderr b/src/test/ui/array-slice-vec/array-not-vector.stderr
new file mode 100644
index 000000000..0e187d907
--- /dev/null
+++ b/src/test/ui/array-slice-vec/array-not-vector.stderr
@@ -0,0 +1,22 @@
+error[E0308]: mismatched types
+ --> $DIR/array-not-vector.rs:2:19
+ |
+LL | let _x: i32 = [1, 2, 3];
+ | --- ^^^^^^^^^ expected `i32`, found array `[{integer}; 3]`
+ | |
+ | expected due to this
+
+error[E0308]: mismatched types
+ --> $DIR/array-not-vector.rs:7:20
+ |
+LL | let _y: &i32 = x;
+ | ---- ^ expected `i32`, found slice `[i32]`
+ | |
+ | expected due to this
+ |
+ = note: expected reference `&i32`
+ found reference `&[i32]`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/array-slice-vec/array_const_index-0.rs b/src/test/ui/array-slice-vec/array_const_index-0.rs
new file mode 100644
index 000000000..9ff7e2c56
--- /dev/null
+++ b/src/test/ui/array-slice-vec/array_const_index-0.rs
@@ -0,0 +1,9 @@
+const A: &'static [i32] = &[];
+const B: i32 = (&A)[1];
+//~^ index out of bounds: the length is 0 but the index is 1
+//~| ERROR any use of this value will cause an error
+//~| WARN this was previously accepted by the compiler but is being phased out
+
+fn main() {
+ let _ = B;
+}
diff --git a/src/test/ui/array-slice-vec/array_const_index-0.stderr b/src/test/ui/array-slice-vec/array_const_index-0.stderr
new file mode 100644
index 000000000..483239871
--- /dev/null
+++ b/src/test/ui/array-slice-vec/array_const_index-0.stderr
@@ -0,0 +1,23 @@
+error: any use of this value will cause an error
+ --> $DIR/array_const_index-0.rs:2:16
+ |
+LL | const B: i32 = (&A)[1];
+ | ------------ ^^^^^^^ index out of bounds: the length is 0 but the index is 1
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: aborting due to previous error
+
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/array_const_index-0.rs:2:16
+ |
+LL | const B: i32 = (&A)[1];
+ | ------------ ^^^^^^^ index out of bounds: the length is 0 but the index is 1
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/array-slice-vec/array_const_index-1.rs b/src/test/ui/array-slice-vec/array_const_index-1.rs
new file mode 100644
index 000000000..f4326189c
--- /dev/null
+++ b/src/test/ui/array-slice-vec/array_const_index-1.rs
@@ -0,0 +1,9 @@
+const A: [i32; 0] = [];
+const B: i32 = A[1];
+//~^ index out of bounds: the length is 0 but the index is 1
+//~| ERROR any use of this value will cause an error
+//~| WARN this was previously accepted by the compiler but is being phased out
+
+fn main() {
+ let _ = B;
+}
diff --git a/src/test/ui/array-slice-vec/array_const_index-1.stderr b/src/test/ui/array-slice-vec/array_const_index-1.stderr
new file mode 100644
index 000000000..361f518c0
--- /dev/null
+++ b/src/test/ui/array-slice-vec/array_const_index-1.stderr
@@ -0,0 +1,23 @@
+error: any use of this value will cause an error
+ --> $DIR/array_const_index-1.rs:2:16
+ |
+LL | const B: i32 = A[1];
+ | ------------ ^^^^ index out of bounds: the length is 0 but the index is 1
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
+error: aborting due to previous error
+
+Future incompatibility report: Future breakage diagnostic:
+error: any use of this value will cause an error
+ --> $DIR/array_const_index-1.rs:2:16
+ |
+LL | const B: i32 = A[1];
+ | ------------ ^^^^ index out of bounds: the length is 0 but the index is 1
+ |
+ = note: `#[deny(const_err)]` on by default
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
+
diff --git a/src/test/ui/array-slice-vec/array_const_index-2.rs b/src/test/ui/array-slice-vec/array_const_index-2.rs
new file mode 100644
index 000000000..8ee225f5c
--- /dev/null
+++ b/src/test/ui/array-slice-vec/array_const_index-2.rs
@@ -0,0 +1,12 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(stable_features)]
+
+#![feature(const_indexing)]
+
+fn main() {
+ const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47];
+ const IDX: usize = 3;
+ const VAL: i32 = ARR[IDX];
+ const BLUB: [i32; (ARR[0] - 41) as usize] = [5];
+}
diff --git a/src/test/ui/array-slice-vec/bounds-check-no-overflow.rs b/src/test/ui/array-slice-vec/bounds-check-no-overflow.rs
new file mode 100644
index 000000000..577853a4e
--- /dev/null
+++ b/src/test/ui/array-slice-vec/bounds-check-no-overflow.rs
@@ -0,0 +1,10 @@
+// run-fail
+// error-pattern:index out of bounds
+// ignore-emscripten no processes
+
+use std::mem::size_of;
+
+fn main() {
+ let xs = [1, 2, 3];
+ xs[usize::MAX / size_of::<isize>() + 1];
+}
diff --git a/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs
new file mode 100644
index 000000000..2b3ece67b
--- /dev/null
+++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-1.rs
@@ -0,0 +1,53 @@
+// run-pass
+// needs-unwind
+#![allow(overflowing_literals)]
+
+// Test that we cleanup a fixed size Box<[D; k]> properly when D has a
+// destructor.
+
+// ignore-emscripten no threads support
+
+use std::thread;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+static LOG: AtomicUsize = AtomicUsize::new(0);
+
+struct D(u8);
+
+impl Drop for D {
+ fn drop(&mut self) {
+ println!("Dropping {}", self.0);
+ let old = LOG.load(Ordering::SeqCst);
+ let _ = LOG.compare_exchange(
+ old,
+ old << 4 | self.0 as usize,
+ Ordering::SeqCst,
+ Ordering::SeqCst
+ );
+ }
+}
+
+fn main() {
+ fn die() -> D { panic!("Oh no"); }
+ let g = thread::spawn(|| {
+ let _b1: Box<[D; 4]> = Box::new([D( 1), D( 2), D( 3), D( 4)]);
+ let _b2: Box<[D; 4]> = Box::new([D( 5), D( 6), D( 7), D( 8)]);
+ let _b3: Box<[D; 4]> = Box::new([D( 9), D(10), die(), D(12)]);
+ let _b4: Box<[D; 4]> = Box::new([D(13), D(14), D(15), D(16)]);
+ });
+ assert!(g.join().is_err());
+
+ // When the panic occurs, we will be in the midst of constructing
+ // the input to `_b3`. Therefore, we drop the elements of the
+ // partially filled array first, before we get around to dropping
+ // the elements of `_b1` and _b2`.
+
+ // Issue 23222: The order in which the elements actually get
+ // dropped is a little funky. See similar notes in nested-vec-3;
+ // in essence, I would not be surprised if we change the ordering
+ // given in `expect` in the future.
+
+ let expect = 0x__A_9__5_6_7_8__1_2_3_4;
+ let actual = LOG.load(Ordering::SeqCst);
+ assert!(actual == expect, "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
diff --git a/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs
new file mode 100644
index 000000000..c0ca45875
--- /dev/null
+++ b/src/test/ui/array-slice-vec/box-of-array-of-drop-2.rs
@@ -0,0 +1,53 @@
+// run-pass
+// needs-unwind
+#![allow(overflowing_literals)]
+
+// Test that we cleanup dynamic sized Box<[D]> properly when D has a
+// destructor.
+
+// ignore-emscripten no threads support
+
+use std::thread;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+static LOG: AtomicUsize = AtomicUsize::new(0);
+
+struct D(u8);
+
+impl Drop for D {
+ fn drop(&mut self) {
+ println!("Dropping {}", self.0);
+ let old = LOG.load(Ordering::SeqCst);
+ let _ = LOG.compare_exchange(
+ old,
+ old << 4 | self.0 as usize,
+ Ordering::SeqCst,
+ Ordering::SeqCst
+ );
+ }
+}
+
+fn main() {
+ fn die() -> D { panic!("Oh no"); }
+ let g = thread::spawn(|| {
+ let _b1: Box<[D; 4]> = Box::new([D( 1), D( 2), D( 3), D( 4)]);
+ let _b2: Box<[D; 4]> = Box::new([D( 5), D( 6), D( 7), D( 8)]);
+ let _b3: Box<[D; 4]> = Box::new([D( 9), D(10), die(), D(12)]);
+ let _b4: Box<[D; 4]> = Box::new([D(13), D(14), D(15), D(16)]);
+ });
+ assert!(g.join().is_err());
+
+ // When the panic occurs, we will be in the midst of constructing
+ // the input to `_b3`. Therefore, we drop the elements of the
+ // partially filled array first, before we get around to dropping
+ // the elements of `_b1` and _b2`.
+
+ // Issue 23222: The order in which the elements actually get
+ // dropped is a little funky. See similar notes in nested-vec-3;
+ // in essence, I would not be surprised if we change the ordering
+ // given in `expect` in the future.
+
+ let expect = 0x__A_9__5_6_7_8__1_2_3_4;
+ let actual = LOG.load(Ordering::SeqCst);
+ assert!(actual == expect, "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
diff --git a/src/test/ui/array-slice-vec/byte-literals.rs b/src/test/ui/array-slice-vec/byte-literals.rs
new file mode 100644
index 000000000..2649c2eac
--- /dev/null
+++ b/src/test/ui/array-slice-vec/byte-literals.rs
@@ -0,0 +1,67 @@
+// run-pass
+//
+
+
+static FOO: u8 = b'\xF0';
+static BAR: &'static [u8] = b"a\xF0\t";
+static BAR_FIXED: &'static [u8; 3] = b"a\xF0\t";
+static BAZ: &'static [u8] = br"a\n";
+
+pub fn main() {
+ let bar: &'static [u8] = b"a\xF0\t";
+ let bar_fixed: &'static [u8; 3] = b"a\xF0\t";
+
+ assert_eq!(b'a', 97u8);
+ assert_eq!(b'\n', 10u8);
+ assert_eq!(b'\r', 13u8);
+ assert_eq!(b'\t', 9u8);
+ assert_eq!(b'\\', 92u8);
+ assert_eq!(b'\'', 39u8);
+ assert_eq!(b'\"', 34u8);
+ assert_eq!(b'\0', 0u8);
+ assert_eq!(b'\xF0', 240u8);
+ assert_eq!(FOO, 240u8);
+
+ match 42 {
+ b'*' => {},
+ _ => panic!()
+ }
+
+ match 100 {
+ b'a' ..= b'z' => {},
+ _ => panic!()
+ }
+
+ let expected: &[_] = &[97u8, 10u8, 13u8, 9u8, 92u8, 39u8, 34u8, 0u8, 240u8];
+ assert_eq!(b"a\n\r\t\\\'\"\0\xF0", expected);
+ let expected: &[_] = &[97u8, 98u8];
+ assert_eq!(b"a\
+ b", expected);
+ let expected: &[_] = &[97u8, 240u8, 9u8];
+ assert_eq!(BAR, expected);
+ assert_eq!(BAR_FIXED, expected);
+ assert_eq!(bar, expected);
+ assert_eq!(bar_fixed, expected);
+
+ let val = &[97u8, 10u8];
+ match val {
+ b"a\n" => {},
+ _ => panic!(),
+ }
+
+ let buf = vec![97u8, 98, 99, 100];
+ assert_eq!(match &buf[0..3] {
+ b"def" => 1,
+ b"abc" => 2,
+ _ => 3
+ }, 2);
+
+ let expected: &[_] = &[97u8, 92u8, 110u8];
+ assert_eq!(BAZ, expected);
+ let expected: &[_] = &[97u8, 92u8, 110u8];
+ assert_eq!(br"a\n", expected);
+ assert_eq!(br"a\n", b"a\\n");
+ let expected: &[_] = &[97u8, 34u8, 35u8, 35u8, 98u8];
+ assert_eq!(br###"a"##b"###, expected);
+ assert_eq!(br###"a"##b"###, b"a\"##b");
+}
diff --git a/src/test/ui/array-slice-vec/cast-in-array-size.rs b/src/test/ui/array-slice-vec/cast-in-array-size.rs
new file mode 100644
index 000000000..b112dcaef
--- /dev/null
+++ b/src/test/ui/array-slice-vec/cast-in-array-size.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+
+// issues #10618 and #16382
+// pretty-expanded FIXME #23616
+
+const SIZE: isize = 25;
+
+fn main() {
+ let _a: [bool; 1 as usize];
+ let _b: [isize; SIZE as usize] = [1; SIZE as usize];
+ let _c: [bool; '\n' as usize] = [true; '\n' as usize];
+ let _d: [bool; true as usize] = [true; true as usize];
+}
diff --git a/src/test/ui/array-slice-vec/check-static-mut-slices.rs b/src/test/ui/array-slice-vec/check-static-mut-slices.rs
new file mode 100644
index 000000000..b89c63403
--- /dev/null
+++ b/src/test/ui/array-slice-vec/check-static-mut-slices.rs
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(dead_code)]
+
+// Checks that mutable static items can have mutable slices
+
+
+static mut TEST: &'static mut [isize] = &mut [1];
+static mut EMPTY: &'static mut [isize] = &mut [];
+
+pub fn main() {
+ unsafe {
+ TEST[0] += 1;
+ assert_eq!(TEST[0], 2);
+ }
+}
diff --git a/src/test/ui/array-slice-vec/check-static-slice.rs b/src/test/ui/array-slice-vec/check-static-slice.rs
new file mode 100644
index 000000000..1c607d134
--- /dev/null
+++ b/src/test/ui/array-slice-vec/check-static-slice.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+// Check that the various ways of getting to a reference to a vec (both sized
+// and unsized) work properly.
+
+
+const AA: [isize; 3] = [1, 2, 3];
+const AB: &'static [isize; 3] = &AA;
+const AC: &'static [isize] = AB;
+const AD: &'static [isize] = &AA;
+const AE: &'static [isize; 3] = &[1, 2, 3];
+const AF: &'static [isize] = &[1, 2, 3];
+
+static CA: isize = AA[0];
+static CB: isize = AB[1];
+static CC: isize = AC[2];
+static CD: isize = AD[0];
+static CE: isize = AE[1];
+static CF: isize = AF[2];
+
+static AG: &'static isize = &AA[2];
+
+fn main () {
+ let b: &[isize] = &[1, 2, 3];
+ assert_eq!(AC, b);
+ assert_eq!(AD, b);
+ assert_eq!(AF, b);
+ assert_eq!(*AG, 3);
+
+ assert_eq!(CA, 1);
+ assert_eq!(CB, 2);
+ assert_eq!(CC, 3);
+ assert_eq!(CD, 1);
+ assert_eq!(CE, 2);
+ assert_eq!(CF, 3);
+}
diff --git a/src/test/ui/array-slice-vec/copy-out-of-array-1.rs b/src/test/ui/array-slice-vec/copy-out-of-array-1.rs
new file mode 100644
index 000000000..c6d311148
--- /dev/null
+++ b/src/test/ui/array-slice-vec/copy-out-of-array-1.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+// Ensure that we can copy out of a fixed-size array.
+//
+// (Compare with ui/moves/move-out-of-array-1.rs)
+
+#[derive(Copy, Clone)]
+struct C { _x: u8 }
+
+fn main() {
+ fn d() -> C { C { _x: 0 } }
+
+ let _d1 = foo([d(), d(), d(), d()], 1);
+ let _d3 = foo([d(), d(), d(), d()], 3);
+}
+
+fn foo(a: [C; 4], i: usize) -> C {
+ a[i]
+}
diff --git a/src/test/ui/array-slice-vec/destructure-array-1.rs b/src/test/ui/array-slice-vec/destructure-array-1.rs
new file mode 100644
index 000000000..74d893ee5
--- /dev/null
+++ b/src/test/ui/array-slice-vec/destructure-array-1.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+// Ensure that we can do a destructuring bind of a fixed-size array,
+// even when the element type has a destructor.
+
+struct D { x: u8 }
+
+impl Drop for D { fn drop(&mut self) { } }
+
+fn main() {
+ fn d(x: u8) -> D { D { x: x } }
+
+ let d1 = foo([d(1), d(2), d(3), d(4)], 1);
+ let d3 = foo([d(5), d(6), d(7), d(8)], 3);
+ assert_eq!(d1.x, 2);
+ assert_eq!(d3.x, 8);
+}
+
+fn foo([a, b, c, d]: [D; 4], i: usize) -> D {
+ match i {
+ 0 => a,
+ 1 => b,
+ 2 => c,
+ 3 => d,
+ _ => panic!("unmatched"),
+ }
+}
diff --git a/src/test/ui/array-slice-vec/dst-raw-slice.rs b/src/test/ui/array-slice-vec/dst-raw-slice.rs
new file mode 100644
index 000000000..371d16f09
--- /dev/null
+++ b/src/test/ui/array-slice-vec/dst-raw-slice.rs
@@ -0,0 +1,13 @@
+// Test bounds checking for DST raw slices
+
+// run-fail
+// error-pattern:index out of bounds
+// ignore-emscripten no processes
+
+#[allow(unconditional_panic)]
+fn main() {
+ let a: *const [_] = &[1, 2, 3];
+ unsafe {
+ let _b = (*a)[3];
+ }
+}
diff --git a/src/test/ui/array-slice-vec/empty-mutable-vec.rs b/src/test/ui/array-slice-vec/empty-mutable-vec.rs
new file mode 100644
index 000000000..91ab280b9
--- /dev/null
+++ b/src/test/ui/array-slice-vec/empty-mutable-vec.rs
@@ -0,0 +1,8 @@
+// run-pass
+
+// pretty-expanded FIXME #23616
+
+#![allow(unused_mut)]
+
+
+pub fn main() { let mut _v: Vec<isize> = Vec::new(); }
diff --git a/src/test/ui/array-slice-vec/estr-slice.rs b/src/test/ui/array-slice-vec/estr-slice.rs
new file mode 100644
index 000000000..cd2c17220
--- /dev/null
+++ b/src/test/ui/array-slice-vec/estr-slice.rs
@@ -0,0 +1,50 @@
+// run-pass
+
+
+pub fn main() {
+ let x = "hello";
+ let v = "hello";
+ let y : &str = "there";
+
+ println!("{}", x);
+ println!("{}", y);
+
+ assert_eq!(x.as_bytes()[0], 'h' as u8);
+ assert_eq!(x.as_bytes()[4], 'o' as u8);
+
+ let z : &str = "thing";
+ assert_eq!(v, x);
+ assert_ne!(x, z);
+
+ let a = "aaaa";
+ let b = "bbbb";
+
+ let c = "cccc";
+ let cc = "ccccc";
+
+ println!("{}", a);
+
+ assert!(a < b);
+ assert!(a <= b);
+ assert_ne!(a, b);
+ assert!(b >= a);
+ assert!(b > a);
+
+ println!("{}", b);
+
+ assert!(a < c);
+ assert!(a <= c);
+ assert_ne!(a, c);
+ assert!(c >= a);
+ assert!(c > a);
+
+ println!("{}", c);
+
+ assert!(c < cc);
+ assert!(c <= cc);
+ assert_ne!(c, cc);
+ assert!(cc >= c);
+ assert!(cc > c);
+
+ println!("{}", cc);
+}
diff --git a/src/test/ui/array-slice-vec/evec-slice.rs b/src/test/ui/array-slice-vec/evec-slice.rs
new file mode 100644
index 000000000..4bdf2dbdd
--- /dev/null
+++ b/src/test/ui/array-slice-vec/evec-slice.rs
@@ -0,0 +1,47 @@
+// run-pass
+#![allow(unused_assignments)]
+
+pub fn main() {
+ let x : &[isize] = &[1,2,3,4,5];
+ let mut z : &[isize] = &[1,2,3,4,5];
+ z = x;
+ assert_eq!(z[0], 1);
+ assert_eq!(z[4], 5);
+
+ let a : &[isize] = &[1,1,1,1,1];
+ let b : &[isize] = &[2,2,2,2,2];
+ let c : &[isize] = &[2,2,2,2,3];
+ let cc : &[isize] = &[2,2,2,2,2,2];
+
+ println!("{:?}", a);
+
+ assert!(a < b);
+ assert!(a <= b);
+ assert!(a != b);
+ assert!(b >= a);
+ assert!(b > a);
+
+ println!("{:?}", b);
+
+ assert!(b < c);
+ assert!(b <= c);
+ assert!(b != c);
+ assert!(c >= b);
+ assert!(c > b);
+
+ assert!(a < c);
+ assert!(a <= c);
+ assert!(a != c);
+ assert!(c >= a);
+ assert!(c > a);
+
+ println!("{:?}", c);
+
+ assert!(a < cc);
+ assert!(a <= cc);
+ assert!(a != cc);
+ assert!(cc >= a);
+ assert!(cc > a);
+
+ println!("{:?}", cc);
+}
diff --git a/src/test/ui/array-slice-vec/fixed_length_copy.rs b/src/test/ui/array-slice-vec/fixed_length_copy.rs
new file mode 100644
index 000000000..f73173e84
--- /dev/null
+++ b/src/test/ui/array-slice-vec/fixed_length_copy.rs
@@ -0,0 +1,9 @@
+// run-pass
+
+
+pub fn main() {
+ let arr = [1,2,3];
+ let arr2 = arr;
+ assert_eq!(arr[1], 2);
+ assert_eq!(arr2[2], 3);
+}
diff --git a/src/test/ui/array-slice-vec/huge-largest-array.rs b/src/test/ui/array-slice-vec/huge-largest-array.rs
new file mode 100644
index 000000000..9e78162c8
--- /dev/null
+++ b/src/test/ui/array-slice-vec/huge-largest-array.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+
+use std::mem::size_of;
+
+#[cfg(target_pointer_width = "32")]
+pub fn main() {
+ assert_eq!(size_of::<[u8; (1 << 31) - 1]>(), (1 << 31) - 1);
+}
+
+#[cfg(target_pointer_width = "64")]
+pub fn main() {
+ assert_eq!(size_of::<[u8; (1 << 47) - 1]>(), (1 << 47) - 1);
+}
diff --git a/src/test/ui/array-slice-vec/infer_array_len.rs b/src/test/ui/array-slice-vec/infer_array_len.rs
new file mode 100644
index 000000000..22fe7cb88
--- /dev/null
+++ b/src/test/ui/array-slice-vec/infer_array_len.rs
@@ -0,0 +1,21 @@
+// see issue #70529
+struct A;
+
+impl From<A> for [u8; 2] {
+ fn from(a: A) -> Self {
+ [0; 2]
+ }
+}
+
+impl From<A> for [u8; 3] {
+ fn from(a: A) -> Self {
+ [0; 3]
+ }
+}
+
+
+fn main() {
+ let a = A;
+ let [_, _] = a.into();
+ //~^ ERROR type annotations needed
+}
diff --git a/src/test/ui/array-slice-vec/infer_array_len.stderr b/src/test/ui/array-slice-vec/infer_array_len.stderr
new file mode 100644
index 000000000..919550cac
--- /dev/null
+++ b/src/test/ui/array-slice-vec/infer_array_len.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/infer_array_len.rs:19:9
+ |
+LL | let [_, _] = a.into();
+ | ^^^^^^
+ |
+help: consider giving this pattern a type
+ |
+LL | let [_, _]: _ = a.into();
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/array-slice-vec/issue-15730.rs b/src/test/ui/array-slice-vec/issue-15730.rs
new file mode 100644
index 000000000..dacffd154
--- /dev/null
+++ b/src/test/ui/array-slice-vec/issue-15730.rs
@@ -0,0 +1,9 @@
+// run-pass
+#![allow(unused_mut)]
+#![allow(unused_variables)]
+// pretty-expanded FIXME #23616
+
+fn main() {
+ let mut array = [1, 2, 3];
+ let pie_slice = &array[1..2];
+}
diff --git a/src/test/ui/array-slice-vec/issue-18425.rs b/src/test/ui/array-slice-vec/issue-18425.rs
new file mode 100644
index 000000000..354c14a75
--- /dev/null
+++ b/src/test/ui/array-slice-vec/issue-18425.rs
@@ -0,0 +1,9 @@
+// run-pass
+// Check that codegen doesn't ICE when codegenning an array repeat
+// expression with a count of 1 and a non-Copy element type.
+
+// pretty-expanded FIXME #23616
+
+fn main() {
+ let _ = [Box::new(1_usize); 1];
+}
diff --git a/src/test/ui/array-slice-vec/issue-69103-extra-binding-subslice.rs b/src/test/ui/array-slice-vec/issue-69103-extra-binding-subslice.rs
new file mode 100644
index 000000000..061b0d675
--- /dev/null
+++ b/src/test/ui/array-slice-vec/issue-69103-extra-binding-subslice.rs
@@ -0,0 +1,18 @@
+// We used to not lower the extra `b @ ..` into `b @ _` which meant that no type
+// was registered for the binding `b` although it passed through resolve.
+// This resulted in an ICE (#69103).
+
+fn main() {
+ let [a @ .., b @ ..] = &mut [1, 2];
+ //~^ ERROR `..` can only be used once per slice pattern
+ b;
+
+ let [.., c @ ..] = [1, 2];
+ //~^ ERROR `..` can only be used once per slice pattern
+ c;
+
+ // This never ICEd, but let's make sure it won't regress either.
+ let (.., d @ ..) = (1, 2);
+ //~^ ERROR `..` patterns are not allowed here
+ d;
+}
diff --git a/src/test/ui/array-slice-vec/issue-69103-extra-binding-subslice.stderr b/src/test/ui/array-slice-vec/issue-69103-extra-binding-subslice.stderr
new file mode 100644
index 000000000..9432e2f0c
--- /dev/null
+++ b/src/test/ui/array-slice-vec/issue-69103-extra-binding-subslice.stderr
@@ -0,0 +1,26 @@
+error: `..` can only be used once per slice pattern
+ --> $DIR/issue-69103-extra-binding-subslice.rs:6:22
+ |
+LL | let [a @ .., b @ ..] = &mut [1, 2];
+ | -- ^^ can only be used once per slice pattern
+ | |
+ | previously used here
+
+error: `..` can only be used once per slice pattern
+ --> $DIR/issue-69103-extra-binding-subslice.rs:10:18
+ |
+LL | let [.., c @ ..] = [1, 2];
+ | -- ^^ can only be used once per slice pattern
+ | |
+ | previously used here
+
+error: `..` patterns are not allowed here
+ --> $DIR/issue-69103-extra-binding-subslice.rs:15:18
+ |
+LL | let (.., d @ ..) = (1, 2);
+ | ^^
+ |
+ = note: only allowed in tuple, tuple struct, and slice patterns
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/array-slice-vec/ivec-pass-by-value.rs b/src/test/ui/array-slice-vec/ivec-pass-by-value.rs
new file mode 100644
index 000000000..e22aef963
--- /dev/null
+++ b/src/test/ui/array-slice-vec/ivec-pass-by-value.rs
@@ -0,0 +1,4 @@
+// run-pass
+
+fn f(_a: Vec<isize> ) { }
+pub fn main() { f(vec![1, 2, 3, 4, 5]); }
diff --git a/src/test/ui/array-slice-vec/match_arr_unknown_len.rs b/src/test/ui/array-slice-vec/match_arr_unknown_len.rs
new file mode 100644
index 000000000..d190d7054
--- /dev/null
+++ b/src/test/ui/array-slice-vec/match_arr_unknown_len.rs
@@ -0,0 +1,8 @@
+fn is_123<const N: usize>(x: [u32; N]) -> bool {
+ match x {
+ [1, 2] => true, //~ ERROR mismatched types
+ _ => false
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr
new file mode 100644
index 000000000..5e531a993
--- /dev/null
+++ b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/match_arr_unknown_len.rs:3:9
+ |
+LL | [1, 2] => true,
+ | ^^^^^^ expected `2`, found `N`
+ |
+ = note: expected array `[u32; 2]`
+ found array `[u32; N]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/array-slice-vec/mut-vstore-expr.rs b/src/test/ui/array-slice-vec/mut-vstore-expr.rs
new file mode 100644
index 000000000..75b309a48
--- /dev/null
+++ b/src/test/ui/array-slice-vec/mut-vstore-expr.rs
@@ -0,0 +1,6 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+pub fn main() {
+ let _x: &mut [isize] = &mut [ 1, 2, 3 ];
+}
diff --git a/src/test/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs b/src/test/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs
new file mode 100644
index 000000000..7afb9d846
--- /dev/null
+++ b/src/test/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+
+fn test1() {
+ let mut ints = [0; 32];
+ ints[0] += 1;
+ assert_eq!(ints[0], 1);
+}
+
+fn test2() {
+ let mut ints = [0; 32];
+ for i in &mut ints { *i += 22; }
+ for i in &ints { assert_eq!(*i, 22); }
+}
+
+pub fn main() {
+ test1();
+ test2();
+}
diff --git a/src/test/ui/array-slice-vec/mutable-alias-vec.rs b/src/test/ui/array-slice-vec/mutable-alias-vec.rs
new file mode 100644
index 000000000..98dd46824
--- /dev/null
+++ b/src/test/ui/array-slice-vec/mutable-alias-vec.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+fn grow(v: &mut Vec<isize> ) {
+ v.push(1);
+}
+
+pub fn main() {
+ let mut v: Vec<isize> = Vec::new();
+ grow(&mut v);
+ grow(&mut v);
+ grow(&mut v);
+ let len = v.len();
+ println!("{}", len);
+ assert_eq!(len, 3 as usize);
+}
diff --git a/src/test/ui/array-slice-vec/nested-vec-1.rs b/src/test/ui/array-slice-vec/nested-vec-1.rs
new file mode 100644
index 000000000..02a3ccf46
--- /dev/null
+++ b/src/test/ui/array-slice-vec/nested-vec-1.rs
@@ -0,0 +1,8 @@
+// run-pass
+
+// Test that using the `vec!` macro nested within itself works
+
+fn main() {
+ let nested = vec![vec![1u32, 2u32, 3u32]];
+ assert_eq!(nested[0][1], 2);
+}
diff --git a/src/test/ui/array-slice-vec/nested-vec-2.rs b/src/test/ui/array-slice-vec/nested-vec-2.rs
new file mode 100644
index 000000000..d4a704d76
--- /dev/null
+++ b/src/test/ui/array-slice-vec/nested-vec-2.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+// Test that using the `vec!` macro nested within itself works
+// when the contents implement Drop
+
+struct D(u32);
+
+impl Drop for D {
+ fn drop(&mut self) { println!("Dropping {}", self.0); }
+}
+
+fn main() {
+ let nested = vec![vec![D(1u32), D(2u32), D(3u32)]];
+ assert_eq!(nested[0][1].0, 2);
+}
diff --git a/src/test/ui/array-slice-vec/nested-vec-3.rs b/src/test/ui/array-slice-vec/nested-vec-3.rs
new file mode 100644
index 000000000..b3ae683a8
--- /dev/null
+++ b/src/test/ui/array-slice-vec/nested-vec-3.rs
@@ -0,0 +1,60 @@
+// run-pass
+// needs-unwind
+#![allow(overflowing_literals)]
+
+// ignore-emscripten no threads support
+
+// Test that using the `vec!` macro nested within itself works when
+// the contents implement Drop and we hit a panic in the middle of
+// construction.
+
+use std::thread;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+static LOG: AtomicUsize = AtomicUsize::new(0);
+
+struct D(u8);
+
+impl Drop for D {
+ fn drop(&mut self) {
+ println!("Dropping {}", self.0);
+ let old = LOG.load(Ordering::SeqCst);
+ let _ = LOG.compare_exchange(
+ old,
+ old << 4 | self.0 as usize,
+ Ordering::SeqCst,
+ Ordering::SeqCst,
+ );
+ }
+}
+
+fn main() {
+ fn die() -> D { panic!("Oh no"); }
+ let g = thread::spawn(|| {
+ let _nested = vec![vec![D( 1), D( 2), D( 3), D( 4)],
+ vec![D( 5), D( 6), D( 7), D( 8)],
+ vec![D( 9), D(10), die(), D(12)],
+ vec![D(13), D(14), D(15), D(16)]];
+ });
+ assert!(g.join().is_err());
+
+ // When the panic occurs, we will be in the midst of constructing the
+ // second inner vector. Therefore, we drop the elements of the
+ // partially filled vector first, before we get around to dropping
+ // the elements of the filled vector.
+
+ // Issue 23222: The order in which the elements actually get
+ // dropped is a little funky: as noted above, we'll drop the 9+10
+ // first, but due to #23222, they get dropped in reverse
+ // order. Likewise, again due to #23222, we will drop the second
+ // filled vec before the first filled vec.
+ //
+ // If Issue 23222 is "fixed", then presumably the corrected
+ // expected order of events will be 0x__9_A__1_2_3_4__5_6_7_8;
+ // that is, we would still drop 9+10 first, since they belong to
+ // the more deeply nested expression when the panic occurs.
+
+ let expect = 0x__A_9__5_6_7_8__1_2_3_4;
+ let actual = LOG.load(Ordering::SeqCst);
+ assert!(actual == expect, "expect: 0x{:x} actual: 0x{:x}", expect, actual);
+}
diff --git a/src/test/ui/array-slice-vec/new-style-fixed-length-vec.rs b/src/test/ui/array-slice-vec/new-style-fixed-length-vec.rs
new file mode 100644
index 000000000..454f94be8
--- /dev/null
+++ b/src/test/ui/array-slice-vec/new-style-fixed-length-vec.rs
@@ -0,0 +1,7 @@
+// run-pass
+
+static FOO: [isize; 3] = [1, 2, 3];
+
+pub fn main() {
+ println!("{} {} {}", FOO[0], FOO[1], FOO[2]);
+}
diff --git a/src/test/ui/array-slice-vec/rcvr-borrowed-to-slice.rs b/src/test/ui/array-slice-vec/rcvr-borrowed-to-slice.rs
new file mode 100644
index 000000000..17cf7e335
--- /dev/null
+++ b/src/test/ui/array-slice-vec/rcvr-borrowed-to-slice.rs
@@ -0,0 +1,33 @@
+// run-pass
+
+#![allow(non_camel_case_types)]
+
+trait sum {
+ fn sum_(self) -> isize;
+}
+
+// Note: impl on a slice
+impl<'a> sum for &'a [isize] {
+ fn sum_(self) -> isize {
+ self.iter().fold(0, |a, &b| a + b)
+ }
+}
+
+fn call_sum(x: &[isize]) -> isize { x.sum_() }
+
+pub fn main() {
+ let x = vec![1, 2, 3];
+ let y = call_sum(&x);
+ println!("y=={}", y);
+ assert_eq!(y, 6);
+
+ let x = vec![1, 2, 3];
+ let y = x.sum_();
+ println!("y=={}", y);
+ assert_eq!(y, 6);
+
+ let x = vec![1, 2, 3];
+ let y = x.sum_();
+ println!("y=={}", y);
+ assert_eq!(y, 6);
+}
diff --git a/src/test/ui/array-slice-vec/repeat_empty_ok.rs b/src/test/ui/array-slice-vec/repeat_empty_ok.rs
new file mode 100644
index 000000000..25463ea5e
--- /dev/null
+++ b/src/test/ui/array-slice-vec/repeat_empty_ok.rs
@@ -0,0 +1,15 @@
+#![crate_type = "lib"]
+
+pub struct Header<'a> {
+ pub value: &'a [u8],
+}
+
+pub fn test() {
+ let headers = [Header{value: &[]}; 128];
+ //~^ ERROR the trait bound
+}
+
+pub fn test2() {
+ let headers = [Header{value: &[0]}; 128];
+ //~^ ERROR the trait bound
+}
diff --git a/src/test/ui/array-slice-vec/repeat_empty_ok.stderr b/src/test/ui/array-slice-vec/repeat_empty_ok.stderr
new file mode 100644
index 000000000..724bdcd92
--- /dev/null
+++ b/src/test/ui/array-slice-vec/repeat_empty_ok.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied
+ --> $DIR/repeat_empty_ok.rs:8:20
+ |
+LL | let headers = [Header{value: &[]}; 128];
+ | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
+ |
+ = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: consider annotating `Header<'_>` with `#[derive(Copy)]`
+ |
+LL | #[derive(Copy)]
+ |
+
+error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied
+ --> $DIR/repeat_empty_ok.rs:13:20
+ |
+LL | let headers = [Header{value: &[0]}; 128];
+ | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
+ |
+ = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: consider annotating `Header<'_>` with `#[derive(Copy)]`
+ |
+LL | #[derive(Copy)]
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/array-slice-vec/repeated-vector-syntax.rs b/src/test/ui/array-slice-vec/repeated-vector-syntax.rs
new file mode 100644
index 000000000..4458eb06d
--- /dev/null
+++ b/src/test/ui/array-slice-vec/repeated-vector-syntax.rs
@@ -0,0 +1,13 @@
+// run-pass
+
+pub fn main() {
+ let x = [ [true]; 512 ];
+ let y = [ 0; 1 ];
+
+ print!("[");
+ for xi in &x[..] {
+ print!("{:?}, ", &xi[..]);
+ }
+ println!("]");
+ println!("{:?}", &y[..]);
+}
diff --git a/src/test/ui/array-slice-vec/show-boxed-slice.rs b/src/test/ui/array-slice-vec/show-boxed-slice.rs
new file mode 100644
index 000000000..c10f779b1
--- /dev/null
+++ b/src/test/ui/array-slice-vec/show-boxed-slice.rs
@@ -0,0 +1,8 @@
+// run-pass
+
+#[derive(Debug)]
+struct Foo(#[allow(unused_tuple_struct_fields)] Box<[u8]>);
+
+pub fn main() {
+ println!("{:?}", Foo(Box::new([0, 1, 2])));
+}
diff --git a/src/test/ui/array-slice-vec/slice-2.rs b/src/test/ui/array-slice-vec/slice-2.rs
new file mode 100644
index 000000000..5423e295a
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-2.rs
@@ -0,0 +1,11 @@
+// Test that slicing syntax gives errors if we have not implemented the trait.
+
+struct Foo;
+
+fn main() {
+ let x = Foo;
+ &x[..]; //~ ERROR cannot index into a value of type `Foo`
+ &x[Foo..]; //~ ERROR cannot index into a value of type `Foo`
+ &x[..Foo]; //~ ERROR cannot index into a value of type `Foo`
+ &x[Foo..Foo]; //~ ERROR cannot index into a value of type `Foo`
+}
diff --git a/src/test/ui/array-slice-vec/slice-2.stderr b/src/test/ui/array-slice-vec/slice-2.stderr
new file mode 100644
index 000000000..561feb90f
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-2.stderr
@@ -0,0 +1,27 @@
+error[E0608]: cannot index into a value of type `Foo`
+ --> $DIR/slice-2.rs:7:6
+ |
+LL | &x[..];
+ | ^^^^^
+
+error[E0608]: cannot index into a value of type `Foo`
+ --> $DIR/slice-2.rs:8:6
+ |
+LL | &x[Foo..];
+ | ^^^^^^^^
+
+error[E0608]: cannot index into a value of type `Foo`
+ --> $DIR/slice-2.rs:9:6
+ |
+LL | &x[..Foo];
+ | ^^^^^^^^
+
+error[E0608]: cannot index into a value of type `Foo`
+ --> $DIR/slice-2.rs:10:6
+ |
+LL | &x[Foo..Foo];
+ | ^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0608`.
diff --git a/src/test/ui/array-slice-vec/slice-mut-2.rs b/src/test/ui/array-slice-vec/slice-mut-2.rs
new file mode 100644
index 000000000..216edbb78
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-mut-2.rs
@@ -0,0 +1,8 @@
+// Test mutability and slicing syntax.
+
+fn main() {
+ let x: &[isize] = &[1, 2, 3, 4, 5];
+ // Can't mutably slice an immutable slice
+ let slice: &mut [isize] = &mut [0, 1];
+ let _ = &mut x[2..4]; //~ERROR cannot borrow `*x` as mutable, as it is behind a `&` reference
+}
diff --git a/src/test/ui/array-slice-vec/slice-mut-2.stderr b/src/test/ui/array-slice-vec/slice-mut-2.stderr
new file mode 100644
index 000000000..bad026877
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-mut-2.stderr
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
+ --> $DIR/slice-mut-2.rs:7:18
+ |
+LL | let x: &[isize] = &[1, 2, 3, 4, 5];
+ | ---------------- help: consider changing this to be a mutable reference: `&mut [1, 2, 3, 4, 5]`
+...
+LL | let _ = &mut x[2..4];
+ | ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/array-slice-vec/slice-mut.rs b/src/test/ui/array-slice-vec/slice-mut.rs
new file mode 100644
index 000000000..e9989f0f4
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-mut.rs
@@ -0,0 +1,12 @@
+// Test mutability and slicing syntax.
+
+fn main() {
+ let x: &[isize] = &[1, 2, 3, 4, 5];
+ // Immutable slices are not mutable.
+
+ let y: &mut[_] = &x[2..4];
+ //~^ ERROR mismatched types
+ //~| expected mutable reference `&mut [_]`
+ //~| found reference `&[isize]`
+ //~| types differ in mutability
+}
diff --git a/src/test/ui/array-slice-vec/slice-mut.stderr b/src/test/ui/array-slice-vec/slice-mut.stderr
new file mode 100644
index 000000000..7d34defc1
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-mut.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/slice-mut.rs:7:22
+ |
+LL | let y: &mut[_] = &x[2..4];
+ | ------- ^^^^^^^^ types differ in mutability
+ | |
+ | expected due to this
+ |
+ = note: expected mutable reference `&mut [_]`
+ found reference `&[isize]`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/array-slice-vec/slice-of-zero-size-elements.rs b/src/test/ui/array-slice-vec/slice-of-zero-size-elements.rs
new file mode 100644
index 000000000..83b08a3db
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-of-zero-size-elements.rs
@@ -0,0 +1,53 @@
+// run-pass
+#![allow(stable_features)]
+
+// compile-flags: -C debug-assertions
+
+#![feature(iter_to_slice)]
+
+use std::slice;
+
+fn foo<T>(v: &[T]) -> Option<&[T]> {
+ let mut it = v.iter();
+ for _ in 0..5 {
+ let _ = it.next();
+ }
+ Some(it.as_slice())
+}
+
+fn foo_mut<T>(v: &mut [T]) -> Option<&mut [T]> {
+ let mut it = v.iter_mut();
+ for _ in 0..5 {
+ let _ = it.next();
+ }
+ Some(it.into_slice())
+}
+
+pub fn main() {
+ // In a slice of zero-size elements the pointer is meaningless.
+ // Ensure iteration still works even if the pointer is at the end of the address space.
+ let slice: &[()] = unsafe { slice::from_raw_parts(-5isize as *const (), 10) };
+ assert_eq!(slice.len(), 10);
+ assert_eq!(slice.iter().count(), 10);
+
+ // .nth() on the iterator should also behave correctly
+ let mut it = slice.iter();
+ assert!(it.nth(5).is_some());
+ assert_eq!(it.count(), 4);
+
+ // Converting Iter to a slice should never have a null pointer
+ assert!(foo(slice).is_some());
+
+ // Test mutable iterators as well
+ let slice: &mut [()] = unsafe { slice::from_raw_parts_mut(-5isize as *mut (), 10) };
+ assert_eq!(slice.len(), 10);
+ assert_eq!(slice.iter_mut().count(), 10);
+
+ {
+ let mut it = slice.iter_mut();
+ assert!(it.nth(5).is_some());
+ assert_eq!(it.count(), 4);
+ }
+
+ assert!(foo_mut(slice).is_some())
+}
diff --git a/src/test/ui/array-slice-vec/slice-panic-1.rs b/src/test/ui/array-slice-vec/slice-panic-1.rs
new file mode 100644
index 000000000..3829078ab
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-panic-1.rs
@@ -0,0 +1,27 @@
+// run-pass
+// needs-unwind
+
+// ignore-emscripten no threads support
+
+// Test that if a slicing expr[..] fails, the correct cleanups happen.
+
+
+use std::thread;
+
+struct Foo;
+
+static mut DTOR_COUNT: isize = 0;
+
+impl Drop for Foo {
+ fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } }
+}
+
+fn foo() {
+ let x: &[_] = &[Foo, Foo];
+ let _ = &x[3..4];
+}
+
+fn main() {
+ let _ = thread::spawn(move|| foo()).join();
+ unsafe { assert_eq!(DTOR_COUNT, 2); }
+}
diff --git a/src/test/ui/array-slice-vec/slice-panic-2.rs b/src/test/ui/array-slice-vec/slice-panic-2.rs
new file mode 100644
index 000000000..d83c611d3
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-panic-2.rs
@@ -0,0 +1,31 @@
+// run-pass
+// needs-unwind
+
+// ignore-emscripten no threads support
+
+// Test that if a slicing expr[..] fails, the correct cleanups happen.
+
+
+use std::thread;
+
+struct Foo;
+
+static mut DTOR_COUNT: isize = 0;
+
+impl Drop for Foo {
+ fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } }
+}
+
+fn bar() -> usize {
+ panic!();
+}
+
+fn foo() {
+ let x: &[_] = &[Foo, Foo];
+ let _ = &x[3..bar()];
+}
+
+fn main() {
+ let _ = thread::spawn(move|| foo()).join();
+ unsafe { assert_eq!(DTOR_COUNT, 2); }
+}
diff --git a/src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs
new file mode 100644
index 000000000..521b898e7
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs
@@ -0,0 +1,36 @@
+fn main() {
+ match "foo".to_string() {
+ ['f', 'o', ..] => {}
+ //~^ ERROR expected an array or slice, found `String`
+ _ => { }
+ };
+
+ // Note that this one works with default binding modes.
+ match &[0, 1, 2] {
+ [..] => {}
+ };
+
+ match &[0, 1, 2] {
+ &[..] => {} // ok
+ };
+
+ match [0, 1, 2] {
+ [0] => {}, //~ ERROR pattern requires
+
+ [0, 1, x @ ..] => {
+ let a: [_; 1] = x;
+ }
+ [0, 1, 2, 3, x @ ..] => {} //~ ERROR pattern requires
+ };
+
+ match does_not_exist { //~ ERROR cannot find value `does_not_exist` in this scope
+ [] => {}
+ };
+}
+
+fn another_fn_to_avoid_suppression() {
+ match Default::default()
+ {
+ [] => {} //~ ERROR type annotations needed
+ };
+}
diff --git a/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr
new file mode 100644
index 000000000..70a4cbebe
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr
@@ -0,0 +1,34 @@
+error[E0425]: cannot find value `does_not_exist` in this scope
+ --> $DIR/slice-pat-type-mismatches.rs:26:11
+ |
+LL | match does_not_exist {
+ | ^^^^^^^^^^^^^^ not found in this scope
+
+error[E0529]: expected an array or slice, found `String`
+ --> $DIR/slice-pat-type-mismatches.rs:3:9
+ |
+LL | ['f', 'o', ..] => {}
+ | ^^^^^^^^^^^^^^ pattern cannot match with input type `String`
+
+error[E0527]: pattern requires 1 element but array has 3
+ --> $DIR/slice-pat-type-mismatches.rs:18:9
+ |
+LL | [0] => {},
+ | ^^^ expected 3 elements
+
+error[E0528]: pattern requires at least 4 elements but array has 3
+ --> $DIR/slice-pat-type-mismatches.rs:23:9
+ |
+LL | [0, 1, 2, 3, x @ ..] => {}
+ | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements
+
+error[E0282]: type annotations needed
+ --> $DIR/slice-pat-type-mismatches.rs:34:9
+ |
+LL | [] => {}
+ | ^^ cannot infer type
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0282, E0425, E0527, E0528, E0529.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/array-slice-vec/slice-to-vec-comparison.rs b/src/test/ui/array-slice-vec/slice-to-vec-comparison.rs
new file mode 100644
index 000000000..7026a4900
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-to-vec-comparison.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let a = &[];
+ let b: &Vec<u8> = &vec![];
+ a > b;
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/array-slice-vec/slice-to-vec-comparison.stderr b/src/test/ui/array-slice-vec/slice-to-vec-comparison.stderr
new file mode 100644
index 000000000..e3b3b040f
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice-to-vec-comparison.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/slice-to-vec-comparison.rs:4:9
+ |
+LL | a > b;
+ | ^ expected array of 0 elements, found struct `Vec`
+ |
+ = note: expected reference `&[_; 0]`
+ found reference `&Vec<u8>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/array-slice-vec/slice.rs b/src/test/ui/array-slice-vec/slice.rs
new file mode 100644
index 000000000..a514e2027
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice.rs
@@ -0,0 +1,81 @@
+// run-pass
+#![allow(unused_variables)]
+
+// Test slicing sugar.
+
+extern crate core;
+use core::ops::{Index, IndexMut, Range, RangeTo, RangeFrom, RangeFull};
+
+static mut COUNT: usize = 0;
+
+struct Foo;
+
+impl Index<Range<Foo>> for Foo {
+ type Output = Foo;
+ fn index(&self, index: Range<Foo>) -> &Foo {
+ unsafe { COUNT += 1; }
+ self
+ }
+}
+impl Index<RangeTo<Foo>> for Foo {
+ type Output = Foo;
+ fn index(&self, index: RangeTo<Foo>) -> &Foo {
+ unsafe { COUNT += 1; }
+ self
+ }
+}
+impl Index<RangeFrom<Foo>> for Foo {
+ type Output = Foo;
+ fn index(&self, index: RangeFrom<Foo>) -> &Foo {
+ unsafe { COUNT += 1; }
+ self
+ }
+}
+impl Index<RangeFull> for Foo {
+ type Output = Foo;
+ fn index(&self, _index: RangeFull) -> &Foo {
+ unsafe { COUNT += 1; }
+ self
+ }
+}
+
+impl IndexMut<Range<Foo>> for Foo {
+ fn index_mut(&mut self, index: Range<Foo>) -> &mut Foo {
+ unsafe { COUNT += 1; }
+ self
+ }
+}
+impl IndexMut<RangeTo<Foo>> for Foo {
+ fn index_mut(&mut self, index: RangeTo<Foo>) -> &mut Foo {
+ unsafe { COUNT += 1; }
+ self
+ }
+}
+impl IndexMut<RangeFrom<Foo>> for Foo {
+ fn index_mut(&mut self, index: RangeFrom<Foo>) -> &mut Foo {
+ unsafe { COUNT += 1; }
+ self
+ }
+}
+impl IndexMut<RangeFull> for Foo {
+ fn index_mut(&mut self, _index: RangeFull) -> &mut Foo {
+ unsafe { COUNT += 1; }
+ self
+ }
+}
+
+
+fn main() {
+ let mut x = Foo;
+ let _ = &x[..];
+ let _ = &x[Foo..];
+ let _ = &x[..Foo];
+ let _ = &x[Foo..Foo];
+ let _ = &mut x[..];
+ let _ = &mut x[Foo..];
+ let _ = &mut x[..Foo];
+ let _ = &mut x[Foo..Foo];
+ unsafe {
+ assert_eq!(COUNT, 8);
+ }
+}
diff --git a/src/test/ui/array-slice-vec/slice_binary_search.rs b/src/test/ui/array-slice-vec/slice_binary_search.rs
new file mode 100644
index 000000000..4d8022ecb
--- /dev/null
+++ b/src/test/ui/array-slice-vec/slice_binary_search.rs
@@ -0,0 +1,22 @@
+// run-pass
+
+// Test binary_search_by_key lifetime. Issue #34683
+
+#[allow(dead_code)]
+#[derive(Debug)]
+struct Assignment {
+ topic: String,
+ partition: i32,
+}
+
+fn main() {
+ let xs = vec![
+ Assignment { topic: "abc".into(), partition: 1 },
+ Assignment { topic: "def".into(), partition: 2 },
+ Assignment { topic: "ghi".into(), partition: 3 },
+ ];
+
+ let key: &str = "def";
+ let r = xs.binary_search_by_key(&key, |e| &e.topic);
+ assert_eq!(Ok(1), r.map(|i| i));
+}
diff --git a/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs
new file mode 100644
index 000000000..97e33624b
--- /dev/null
+++ b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs
@@ -0,0 +1,11 @@
+fn main() {
+ let a: &[u8] = &[];
+ match a {
+ [1, tail @ .., tail @ ..] => {},
+ //~^ ERROR identifier `tail` is bound more than once in the same pattern
+ //~| ERROR `..` can only be used once per slice pattern
+ _ => ()
+ }
+}
+
+const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr
new file mode 100644
index 000000000..4d6078788
--- /dev/null
+++ b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr
@@ -0,0 +1,24 @@
+error[E0416]: identifier `tail` is bound more than once in the same pattern
+ --> $DIR/subslice-only-once-semantic-restriction.rs:4:24
+ |
+LL | [1, tail @ .., tail @ ..] => {},
+ | ^^^^ used in a pattern more than once
+
+error: `..` can only be used once per slice pattern
+ --> $DIR/subslice-only-once-semantic-restriction.rs:4:31
+ |
+LL | [1, tail @ .., tail @ ..] => {},
+ | -- ^^ can only be used once per slice pattern
+ | |
+ | previously used here
+
+error[E0308]: mismatched types
+ --> $DIR/subslice-only-once-semantic-restriction.rs:11:30
+ |
+LL | const RECOVERY_WITNESS: () = 0;
+ | ^ expected `()`, found integer
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0416.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs b/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs
new file mode 100644
index 000000000..5a6283e9f
--- /dev/null
+++ b/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs
@@ -0,0 +1,96 @@
+// Test that slice subslice patterns are correctly handled in const evaluation.
+
+// run-pass
+
+#[derive(PartialEq, Debug, Clone)]
+struct N(u8);
+
+#[derive(PartialEq, Debug, Clone)]
+struct Z;
+
+macro_rules! n {
+ ($($e:expr),* $(,)?) => {
+ [$(N($e)),*]
+ }
+}
+
+// This macro has an unused variable so that it can be repeated base on the
+// number of times a repeated variable (`$e` in `z`) occurs.
+macro_rules! zed {
+ ($e:expr) => { Z }
+}
+
+macro_rules! z {
+ ($($e:expr),* $(,)?) => {
+ [$(zed!($e)),*]
+ }
+}
+
+// Compare constant evaluation and runtime evaluation of a given expression.
+macro_rules! compare_evaluation_inner {
+ ($e:expr, $t:ty $(,)?) => {{
+ const CONST_EVAL: $t = $e;
+ const fn const_eval() -> $t { $e }
+ static CONST_EVAL2: $t = const_eval();
+ let runtime_eval = $e;
+ assert_eq!(CONST_EVAL, runtime_eval);
+ assert_eq!(CONST_EVAL2, runtime_eval);
+ }}
+}
+
+// Compare the result of matching `$e` against `$p` using both `if let` and
+// `match`.
+macro_rules! compare_evaluation {
+ ($p:pat, $e:expr, $matches:expr, $t:ty $(,)?) => {{
+ compare_evaluation_inner!(if let $p = $e as &[_] { $matches } else { None }, $t);
+ compare_evaluation_inner!(match $e as &[_] { $p => $matches, _ => None }, $t);
+ }}
+}
+
+// Repeat `$test`, substituting the given macro variables with the given
+// identifiers.
+//
+// For example:
+//
+// repeat! {
+// ($name); X; Y:
+// struct $name;
+// }
+//
+// Expands to:
+//
+// struct X; struct Y;
+//
+// This is used to repeat the tests using both the `N` and `Z`
+// types.
+macro_rules! repeat {
+ (($($dollar:tt $placeholder:ident)*); $($($values:ident),+);*: $($test:tt)*) => {
+ macro_rules! single {
+ ($($dollar $placeholder:ident),*) => { $($test)* }
+ }
+ $(single!($($values),+);)*
+ }
+}
+
+fn main() {
+ repeat! {
+ ($arr $Ty); n, N; z, Z:
+ compare_evaluation!([_, x @ .., _], &$arr!(1, 2, 3, 4), Some(x), Option<&'static [$Ty]>);
+ compare_evaluation!([x, .., _], &$arr!(1, 2, 3, 4), Some(x), Option<&'static $Ty>);
+ compare_evaluation!([_, .., x], &$arr!(1, 2, 3, 4), Some(x), Option<&'static $Ty>);
+
+ compare_evaluation!([_, x @ .., _], &$arr!(1, 2), Some(x), Option<&'static [$Ty]>);
+ compare_evaluation!([x, .., _], &$arr!(1, 2), Some(x), Option<&'static $Ty>);
+ compare_evaluation!([_, .., x], &$arr!(1, 2), Some(x), Option<&'static $Ty>);
+
+ compare_evaluation!([_, x @ .., _], &$arr!(1), Some(x), Option<&'static [$Ty]>);
+ compare_evaluation!([x, .., _], &$arr!(1), Some(x), Option<&'static $Ty>);
+ compare_evaluation!([_, .., x], &$arr!(1), Some(x), Option<&'static $Ty>);
+ }
+
+ compare_evaluation!([N(x), .., _], &n!(1, 2, 3, 4), Some(x), Option<&'static u8>);
+ compare_evaluation!([_, .., N(x)], &n!(1, 2, 3, 4), Some(x), Option<&'static u8>);
+
+ compare_evaluation!([N(x), .., _], &n!(1, 2), Some(x), Option<&'static u8>);
+ compare_evaluation!([_, .., N(x)], &n!(1, 2), Some(x), Option<&'static u8>);
+}
diff --git a/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs b/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs
new file mode 100644
index 000000000..0b793fa01
--- /dev/null
+++ b/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs
@@ -0,0 +1,95 @@
+// Test that array subslice patterns are correctly handled in const evaluation.
+
+// run-pass
+
+#[derive(PartialEq, Debug, Clone)]
+struct N(u8);
+
+#[derive(PartialEq, Debug, Clone)]
+struct Z;
+
+macro_rules! n {
+ ($($e:expr),* $(,)?) => {
+ [$(N($e)),*]
+ }
+}
+
+// This macro has an unused variable so that it can be repeated base on the
+// number of times a repeated variable (`$e` in `z`) occurs.
+macro_rules! zed {
+ ($e:expr) => { Z }
+}
+
+macro_rules! z {
+ ($($e:expr),* $(,)?) => {
+ [$(zed!($e)),*]
+ }
+}
+
+// Compare constant evaluation and runtime evaluation of a given expression.
+macro_rules! compare_evaluation {
+ ($e:expr, $t:ty $(,)?) => {{
+ const CONST_EVAL: $t = $e;
+ const fn const_eval() -> $t { $e }
+ static CONST_EVAL2: $t = const_eval();
+ let runtime_eval = $e;
+ assert_eq!(CONST_EVAL, runtime_eval);
+ assert_eq!(CONST_EVAL2, runtime_eval);
+ }}
+}
+
+// Repeat `$test`, substituting the given macro variables with the given
+// identifiers.
+//
+// For example:
+//
+// repeat! {
+// ($name); X; Y:
+// struct $name;
+// }
+//
+// Expands to:
+//
+// struct X; struct Y;
+//
+// This is used to repeat the tests using both the `N` and `Z`
+// types.
+macro_rules! repeat {
+ (($($dollar:tt $placeholder:ident)*); $($($values:ident),+);*: $($test:tt)*) => {
+ macro_rules! single {
+ ($($dollar $placeholder:ident),*) => { $($test)* }
+ }
+ $(single!($($values),+);)*
+ }
+}
+
+fn main() {
+ repeat! {
+ ($arr $Ty); n, N; z, Z:
+ compare_evaluation!({ let [_, x @ .., _] = $arr!(1, 2, 3, 4); x }, [$Ty; 2]);
+ compare_evaluation!({ let [_, ref x @ .., _] = $arr!(1, 2, 3, 4); x }, &'static [$Ty; 2]);
+ compare_evaluation!({ let [_, x @ .., _] = &$arr!(1, 2, 3, 4); x }, &'static [$Ty; 2]);
+
+ compare_evaluation!({ let [_, _, x @ .., _, _] = $arr!(1, 2, 3, 4); x }, [$Ty; 0]);
+ compare_evaluation!(
+ { let [_, _, ref x @ .., _, _] = $arr!(1, 2, 3, 4); x },
+ &'static [$Ty; 0],
+ );
+ compare_evaluation!(
+ { let [_, _, x @ .., _, _] = &$arr!(1, 2, 3, 4); x },
+ &'static [$Ty; 0],
+ );
+
+ compare_evaluation!({ let [_, .., x] = $arr!(1, 2, 3, 4); x }, $Ty);
+ compare_evaluation!({ let [_, .., ref x] = $arr!(1, 2, 3, 4); x }, &'static $Ty);
+ compare_evaluation!({ let [_, _y @ .., x] = &$arr!(1, 2, 3, 4); x }, &'static $Ty);
+ }
+
+ compare_evaluation!({ let [_, .., N(x)] = n!(1, 2, 3, 4); x }, u8);
+ compare_evaluation!({ let [_, .., N(ref x)] = n!(1, 2, 3, 4); x }, &'static u8);
+ compare_evaluation!({ let [_, .., N(x)] = &n!(1, 2, 3, 4); x }, &'static u8);
+
+ compare_evaluation!({ let [N(x), .., _] = n!(1, 2, 3, 4); x }, u8);
+ compare_evaluation!({ let [N(ref x), .., _] = n!(1, 2, 3, 4); x }, &'static u8);
+ compare_evaluation!({ let [N(x), .., _] = &n!(1, 2, 3, 4); x }, &'static u8);
+}
diff --git a/src/test/ui/array-slice-vec/variance-vec-covariant.rs b/src/test/ui/array-slice-vec/variance-vec-covariant.rs
new file mode 100644
index 000000000..d7e64132f
--- /dev/null
+++ b/src/test/ui/array-slice-vec/variance-vec-covariant.rs
@@ -0,0 +1,20 @@
+// run-pass
+
+// Test that vec is now covariant in its argument type.
+
+#![allow(dead_code)]
+
+fn foo<'a,'b>(v1: Vec<&'a i32>, v2: Vec<&'b i32>) -> i32 {
+ bar(v1, v2).cloned().unwrap_or(0) // only type checks if we can intersect 'a and 'b
+}
+
+fn bar<'c>(v1: Vec<&'c i32>, v2: Vec<&'c i32>) -> Option<&'c i32> {
+ v1.get(0).cloned().or_else(|| v2.get(0).cloned())
+}
+
+fn main() {
+ let x = 22;
+ let y = 44;
+ assert_eq!(foo(vec![&x], vec![&y]), 22);
+ assert_eq!(foo(vec![&y], vec![&x]), 44);
+}
diff --git a/src/test/ui/array-slice-vec/vec-dst.rs b/src/test/ui/array-slice-vec/vec-dst.rs
new file mode 100644
index 000000000..c58ddbc42
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-dst.rs
@@ -0,0 +1,24 @@
+// run-pass
+
+pub fn main() {
+ // Tests for indexing into Box<[T; n]>/& [T; n]
+ let x: [isize; 3] = [1, 2, 3];
+ let mut x: Box<[isize; 3]> = x.into();
+ assert_eq!(x[0], 1);
+ assert_eq!(x[1], 2);
+ assert_eq!(x[2], 3);
+ x[1] = 45;
+ assert_eq!(x[0], 1);
+ assert_eq!(x[1], 45);
+ assert_eq!(x[2], 3);
+
+ let mut x: [isize; 3] = [1, 2, 3];
+ let x: &mut [isize; 3] = &mut x;
+ assert_eq!(x[0], 1);
+ assert_eq!(x[1], 2);
+ assert_eq!(x[2], 3);
+ x[1] = 45;
+ assert_eq!(x[0], 1);
+ assert_eq!(x[1], 45);
+ assert_eq!(x[2], 3);
+}
diff --git a/src/test/ui/array-slice-vec/vec-fixed-length.rs b/src/test/ui/array-slice-vec/vec-fixed-length.rs
new file mode 100644
index 000000000..908c39c79
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-fixed-length.rs
@@ -0,0 +1,24 @@
+// run-pass
+
+
+use std::mem::size_of;
+
+#[cfg(not(target_pointer_width = "64"))]
+fn test_big_vec() {}
+
+#[cfg(target_pointer_width = "64")]
+fn test_big_vec()
+{
+ assert_eq!(size_of::<[u8; 1 << 32]>(), (1 << 32));
+}
+
+fn main() {
+ let x: [isize; 4] = [1, 2, 3, 4];
+ assert_eq!(x[0], 1);
+ assert_eq!(x[1], 2);
+ assert_eq!(x[2], 3);
+ assert_eq!(x[3], 4);
+
+ assert_eq!(size_of::<[u8; 4]>(), 4);
+ test_big_vec();
+}
diff --git a/src/test/ui/array-slice-vec/vec-late-init.rs b/src/test/ui/array-slice-vec/vec-late-init.rs
new file mode 100644
index 000000000..5dee36082
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-late-init.rs
@@ -0,0 +1,9 @@
+// run-pass
+#![allow(unused_mut)]
+
+
+pub fn main() {
+ let mut later: Vec<isize> ;
+ if true { later = vec![1]; } else { later = vec![2]; }
+ println!("{}", later[0]);
+}
diff --git a/src/test/ui/array-slice-vec/vec-macro-no-std.rs b/src/test/ui/array-slice-vec/vec-macro-no-std.rs
new file mode 100644
index 000000000..443895f7c
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-macro-no-std.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+// ignore-emscripten no no_std executables
+
+#![feature(lang_items, start, rustc_private)]
+#![no_std]
+
+extern crate std as other;
+
+extern crate libc;
+
+#[macro_use]
+extern crate alloc;
+
+use alloc::vec::Vec;
+
+// Issue #16806
+
+#[start]
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
+ let x: Vec<u8> = vec![0, 1, 2];
+ match x.last() {
+ Some(&2) => (),
+ _ => panic!(),
+ }
+ 0
+}
diff --git a/src/test/ui/array-slice-vec/vec-macro-rvalue-scope.rs b/src/test/ui/array-slice-vec/vec-macro-rvalue-scope.rs
new file mode 100644
index 000000000..bde010371
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-macro-rvalue-scope.rs
@@ -0,0 +1,11 @@
+// run-pass
+
+
+fn one() -> i32 { 1 }
+
+// Make sure the vec![...] macro doesn't introduce hidden rvalue
+// scopes (such as blocks) around the element expressions.
+pub fn main() {
+ assert_eq!(vec![&one(), &one(), &2], vec![&1, &1, &(one()+one())]);
+ assert_eq!(vec![&one(); 2], vec![&1, &one()]);
+}
diff --git a/src/test/ui/array-slice-vec/vec-macro-with-brackets.rs b/src/test/ui/array-slice-vec/vec-macro-with-brackets.rs
new file mode 100644
index 000000000..6c95bd500
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-macro-with-brackets.rs
@@ -0,0 +1,16 @@
+// run-pass
+#![allow(unused_variables)]
+
+// pretty-expanded FIXME #23616
+
+macro_rules! vec [
+ ($($e:expr),*) => ({
+ let mut _temp = ::std::vec::Vec::new();
+ $(_temp.push($e);)*
+ _temp
+ })
+];
+
+pub fn main() {
+ let my_vec = vec![1, 2, 3, 4, 5];
+}
diff --git a/src/test/ui/array-slice-vec/vec-macro-with-comma-only.rs b/src/test/ui/array-slice-vec/vec-macro-with-comma-only.rs
new file mode 100644
index 000000000..574a53c58
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-macro-with-comma-only.rs
@@ -0,0 +1,3 @@
+pub fn main() {
+ vec![,]; //~ ERROR no rules expected the token `,`
+}
diff --git a/src/test/ui/array-slice-vec/vec-macro-with-comma-only.stderr b/src/test/ui/array-slice-vec/vec-macro-with-comma-only.stderr
new file mode 100644
index 000000000..abbee347c
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-macro-with-comma-only.stderr
@@ -0,0 +1,8 @@
+error: no rules expected the token `,`
+ --> $DIR/vec-macro-with-comma-only.rs:2:10
+ |
+LL | vec![,];
+ | ^ no rules expected this token in macro call
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/array-slice-vec/vec-macro-with-trailing-comma.rs b/src/test/ui/array-slice-vec/vec-macro-with-trailing-comma.rs
new file mode 100644
index 000000000..f7a51f9c4
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-macro-with-trailing-comma.rs
@@ -0,0 +1,8 @@
+// run-pass
+
+
+
+pub fn main() {
+ assert_eq!(vec![1], vec![1,]);
+ assert_eq!(vec![1, 2, 3], vec![1, 2, 3,]);
+}
diff --git a/src/test/ui/array-slice-vec/vec-matching-autoslice.rs b/src/test/ui/array-slice-vec/vec-matching-autoslice.rs
new file mode 100644
index 000000000..8179edf42
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-matching-autoslice.rs
@@ -0,0 +1,23 @@
+// run-pass
+#![allow(illegal_floating_point_literal_pattern)] // FIXME #41620
+
+pub fn main() {
+ let x = [1, 2, 3];
+ match x {
+ [2, _, _] => panic!(),
+ [1, a, b] => {
+ assert_eq!([a, b], [2, 3]);
+ }
+ [_, _, _] => panic!(),
+ }
+
+ let y = ([(1, true), (2, false)], 0.5f64);
+ match y {
+ ([(1, a), (b, false)], _) => {
+ assert_eq!(a, true);
+ assert_eq!(b, 2);
+ }
+ ([_, _], 0.5) => panic!(),
+ ([_, _], _) => panic!(),
+ }
+}
diff --git a/src/test/ui/array-slice-vec/vec-matching-fixed.rs b/src/test/ui/array-slice-vec/vec-matching-fixed.rs
new file mode 100644
index 000000000..fdeb7e4fd
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-matching-fixed.rs
@@ -0,0 +1,30 @@
+// run-pass
+
+fn a() {
+ let x = [1, 2, 3];
+ match x {
+ [1, 2, 4] => unreachable!(),
+ [0, 2, 3, ..] => unreachable!(),
+ [0, .., 3] => unreachable!(),
+ [0, ..] => unreachable!(),
+ [1, 2, 3] => (),
+ [_, _, _] => unreachable!(),
+ }
+ match x {
+ [..] => (),
+ }
+ match x {
+ [_, _, _, ..] => (),
+ }
+ match x {
+ [a, b, c] => {
+ assert_eq!(1, a);
+ assert_eq!(2, b);
+ assert_eq!(3, c);
+ }
+ }
+}
+
+pub fn main() {
+ a();
+}
diff --git a/src/test/ui/array-slice-vec/vec-matching-fold.rs b/src/test/ui/array-slice-vec/vec-matching-fold.rs
new file mode 100644
index 000000000..998899271
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-matching-fold.rs
@@ -0,0 +1,46 @@
+// run-pass
+
+use std::fmt::Debug;
+
+fn foldl<T, U, F>(values: &[T],
+ initial: U,
+ mut function: F)
+ -> U where
+ U: Clone+Debug, T:Debug,
+ F: FnMut(U, &T) -> U,
+{ match values {
+ &[ref head, ref tail @ ..] =>
+ foldl(tail, function(initial, head), function),
+ &[] => {
+ // FIXME: call guards
+ let res = initial.clone(); res
+ }
+ }
+}
+
+fn foldr<T, U, F>(values: &[T],
+ initial: U,
+ mut function: F)
+ -> U where
+ U: Clone,
+ F: FnMut(&T, U) -> U,
+{
+ match values {
+ &[ref head @ .., ref tail] =>
+ foldr(head, function(tail, initial), function),
+ &[] => {
+ // FIXME: call guards
+ let res = initial.clone(); res
+ }
+ }
+}
+
+pub fn main() {
+ let x = &[1, 2, 3, 4, 5];
+
+ let product = foldl(x, 1, |a, b| a * *b);
+ assert_eq!(product, 120);
+
+ let sum = foldr(x, 0, |a, b| *a + b);
+ assert_eq!(sum, 15);
+}
diff --git a/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs
new file mode 100644
index 000000000..ed34f074a
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+#![allow(unused_variables)]
+
+pub fn main() {
+ let x = &[1, 2, 3, 4, 5];
+ let x: &[isize] = &[1, 2, 3, 4, 5];
+ if !x.is_empty() {
+ let el = match x {
+ &[1, ref tail @ ..] => &tail[0],
+ _ => unreachable!()
+ };
+ println!("{}", *el);
+ }
+}
diff --git a/src/test/ui/array-slice-vec/vec-matching.rs b/src/test/ui/array-slice-vec/vec-matching.rs
new file mode 100644
index 000000000..7009244aa
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-matching.rs
@@ -0,0 +1,142 @@
+// run-pass
+
+fn a() {
+ let x = [1];
+ match x {
+ [a] => {
+ assert_eq!(a, 1);
+ }
+ }
+}
+
+fn b() {
+ let x = [1, 2, 3];
+ match x {
+ [a, b, c @ ..] => {
+ assert_eq!(a, 1);
+ assert_eq!(b, 2);
+ let expected: &[_] = &[3];
+ assert_eq!(c, expected);
+ }
+ }
+ match x {
+ [a @ .., b, c] => {
+ let expected: &[_] = &[1];
+ assert_eq!(a, expected);
+ assert_eq!(b, 2);
+ assert_eq!(c, 3);
+ }
+ }
+ match x {
+ [a, b @ .., c] => {
+ assert_eq!(a, 1);
+ let expected: &[_] = &[2];
+ assert_eq!(b, expected);
+ assert_eq!(c, 3);
+ }
+ }
+ match x {
+ [a, b, c] => {
+ assert_eq!(a, 1);
+ assert_eq!(b, 2);
+ assert_eq!(c, 3);
+ }
+ }
+}
+
+
+fn b_slice() {
+ let x : &[_] = &[1, 2, 3];
+ match x {
+ &[a, b, ref c @ ..] => {
+ assert_eq!(a, 1);
+ assert_eq!(b, 2);
+ let expected: &[_] = &[3];
+ assert_eq!(c, expected);
+ }
+ _ => unreachable!()
+ }
+ match x {
+ &[ref a @ .., b, c] => {
+ let expected: &[_] = &[1];
+ assert_eq!(a, expected);
+ assert_eq!(b, 2);
+ assert_eq!(c, 3);
+ }
+ _ => unreachable!()
+ }
+ match x {
+ &[a, ref b @ .., c] => {
+ assert_eq!(a, 1);
+ let expected: &[_] = &[2];
+ assert_eq!(b, expected);
+ assert_eq!(c, 3);
+ }
+ _ => unreachable!()
+ }
+ match x {
+ &[a, b, c] => {
+ assert_eq!(a, 1);
+ assert_eq!(b, 2);
+ assert_eq!(c, 3);
+ }
+ _ => unreachable!()
+ }
+}
+
+fn c() {
+ let x = [1];
+ match x {
+ [2, ..] => panic!(),
+ [..] => ()
+ }
+}
+
+fn d() {
+ let x = [1, 2, 3];
+ let branch = match x {
+ [1, 1, ..] => 0,
+ [1, 2, 3, ..] => 1,
+ [1, 2, ..] => 2,
+ _ => 3
+ };
+ assert_eq!(branch, 1);
+}
+
+fn e() {
+ let x: &[isize] = &[1, 2, 3];
+ let a = match *x {
+ [1, 2] => 0,
+ [..] => 1,
+ };
+
+ assert_eq!(a, 1);
+
+ let b = match *x {
+ [2, ..] => 0,
+ [1, 2, ..] => 1,
+ [_] => 2,
+ [..] => 3
+ };
+
+ assert_eq!(b, 1);
+
+
+ let c = match *x {
+ [_, _, _, _, ..] => 0,
+ [1, 2, ..] => 1,
+ [_] => 2,
+ [..] => 3
+ };
+
+ assert_eq!(c, 1);
+}
+
+pub fn main() {
+ a();
+ b();
+ b_slice();
+ c();
+ d();
+ e();
+}
diff --git a/src/test/ui/array-slice-vec/vec-mut-iter-borrow.rs b/src/test/ui/array-slice-vec/vec-mut-iter-borrow.rs
new file mode 100644
index 000000000..4aa737446
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-mut-iter-borrow.rs
@@ -0,0 +1,7 @@
+fn main() {
+ let mut xs: Vec<isize> = vec![];
+
+ for x in &mut xs {
+ xs.push(1) //~ ERROR cannot borrow `xs`
+ }
+}
diff --git a/src/test/ui/array-slice-vec/vec-mut-iter-borrow.stderr b/src/test/ui/array-slice-vec/vec-mut-iter-borrow.stderr
new file mode 100644
index 000000000..0ec263c85
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-mut-iter-borrow.stderr
@@ -0,0 +1,14 @@
+error[E0499]: cannot borrow `xs` as mutable more than once at a time
+ --> $DIR/vec-mut-iter-borrow.rs:5:9
+ |
+LL | for x in &mut xs {
+ | -------
+ | |
+ | first mutable borrow occurs here
+ | first borrow later used here
+LL | xs.push(1)
+ | ^^^^^^^^^^ second mutable borrow occurs here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/src/test/ui/array-slice-vec/vec-overrun.rs b/src/test/ui/array-slice-vec/vec-overrun.rs
new file mode 100644
index 000000000..bdc7d507d
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-overrun.rs
@@ -0,0 +1,12 @@
+// run-fail
+// error-pattern:index out of bounds: the len is 1 but the index is 2
+// ignore-emscripten no processes
+
+fn main() {
+ let v: Vec<isize> = vec![10];
+ let x: usize = 0;
+ assert_eq!(v[x], 10);
+ // Bounds-check panic.
+
+ assert_eq!(v[x + 2], 20);
+}
diff --git a/src/test/ui/array-slice-vec/vec-repeat-with-cast.rs b/src/test/ui/array-slice-vec/vec-repeat-with-cast.rs
new file mode 100644
index 000000000..3e0e18873
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-repeat-with-cast.rs
@@ -0,0 +1,5 @@
+// run-pass
+
+// pretty-expanded FIXME #23616
+
+pub fn main() { let _a = [0; 1 as usize]; }
diff --git a/src/test/ui/array-slice-vec/vec-res-add.rs b/src/test/ui/array-slice-vec/vec-res-add.rs
new file mode 100644
index 000000000..57b552ee5
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-res-add.rs
@@ -0,0 +1,19 @@
+#[derive(Debug)]
+struct R {
+ i:isize
+}
+
+fn r(i:isize) -> R { R { i: i } }
+
+impl Drop for R {
+ fn drop(&mut self) {}
+}
+
+fn main() {
+ // This can't make sense as it would copy the classes
+ let i = vec![r(0)];
+ let j = vec![r(1)];
+ let k = i + j;
+ //~^ ERROR cannot add `Vec<R>` to `Vec<R>`
+ println!("{:?}", j);
+}
diff --git a/src/test/ui/array-slice-vec/vec-res-add.stderr b/src/test/ui/array-slice-vec/vec-res-add.stderr
new file mode 100644
index 000000000..751127136
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-res-add.stderr
@@ -0,0 +1,11 @@
+error[E0369]: cannot add `Vec<R>` to `Vec<R>`
+ --> $DIR/vec-res-add.rs:16:15
+ |
+LL | let k = i + j;
+ | - ^ - Vec<R>
+ | |
+ | Vec<R>
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/array-slice-vec/vec-tail-matching.rs b/src/test/ui/array-slice-vec/vec-tail-matching.rs
new file mode 100644
index 000000000..5f1699227
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vec-tail-matching.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+struct Foo {
+ string: &'static str
+}
+
+pub fn main() {
+ let x = [
+ Foo { string: "foo" },
+ Foo { string: "bar" },
+ Foo { string: "baz" }
+ ];
+ match x {
+ [ref first, ref tail @ ..] => {
+ assert_eq!(first.string, "foo");
+ assert_eq!(tail.len(), 2);
+ assert_eq!(tail[0].string, "bar");
+ assert_eq!(tail[1].string, "baz");
+
+ match *(tail as &[_]) {
+ [Foo { .. }, _, Foo { .. }, ref _tail @ ..] => {
+ unreachable!();
+ }
+ [Foo { string: ref a }, Foo { string: ref b }] => {
+ assert_eq!("bar", &a[0..a.len()]);
+ assert_eq!("baz", &b[0..b.len()]);
+ }
+ _ => {
+ unreachable!();
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/ui/array-slice-vec/vector-cast-weirdness.rs b/src/test/ui/array-slice-vec/vector-cast-weirdness.rs
new file mode 100644
index 000000000..e8f2c7147
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vector-cast-weirdness.rs
@@ -0,0 +1,34 @@
+// Issue #14893. Tests that casts from vectors don't behave strangely in the
+// presence of the `_` type shorthand notation.
+//
+// Update: after a change to the way casts are done, we have more type information
+// around and so the errors here are no longer exactly the same.
+//
+// Update: With PR #81479 some of the previously rejected cases are now allowed.
+// New test cases added.
+
+struct X {
+ y: [u8; 2],
+}
+
+fn main() {
+ let x1 = X { y: [0, 0] };
+
+ // No longer a type mismatch - the `_` can be fully resolved by type inference.
+ let p1: *const u8 = &x1.y as *const _;
+ let p1: *mut u8 = &x1.y as *mut _;
+ //~^ ERROR: casting `&[u8; 2]` as `*mut u8` is invalid
+ let t1: *const [u8; 2] = &x1.y as *const _;
+ let t1: *mut [u8; 2] = &x1.y as *mut _;
+ //~^ ERROR: casting `&[u8; 2]` as `*mut [u8; 2]` is invalid
+ let h1: *const [u8; 2] = &x1.y as *const [u8; 2];
+ let t1: *mut [u8; 2] = &x1.y as *mut [u8; 2];
+ //~^ ERROR: casting `&[u8; 2]` as `*mut [u8; 2]` is invalid
+
+ let mut x1 = X { y: [0, 0] };
+
+ let p1: *mut u8 = &mut x1.y as *mut _;
+ let p2: *const u8 = &mut x1.y as *const _;
+ let t1: *mut [u8; 2] = &mut x1.y as *mut _;
+ let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2];
+}
diff --git a/src/test/ui/array-slice-vec/vector-cast-weirdness.stderr b/src/test/ui/array-slice-vec/vector-cast-weirdness.stderr
new file mode 100644
index 000000000..6fdb1ac9e
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vector-cast-weirdness.stderr
@@ -0,0 +1,21 @@
+error[E0606]: casting `&[u8; 2]` as `*mut u8` is invalid
+ --> $DIR/vector-cast-weirdness.rs:19:23
+ |
+LL | let p1: *mut u8 = &x1.y as *mut _;
+ | ^^^^^^^^^^^^^^^
+
+error[E0606]: casting `&[u8; 2]` as `*mut [u8; 2]` is invalid
+ --> $DIR/vector-cast-weirdness.rs:22:28
+ |
+LL | let t1: *mut [u8; 2] = &x1.y as *mut _;
+ | ^^^^^^^^^^^^^^^
+
+error[E0606]: casting `&[u8; 2]` as `*mut [u8; 2]` is invalid
+ --> $DIR/vector-cast-weirdness.rs:25:28
+ |
+LL | let t1: *mut [u8; 2] = &x1.y as *mut [u8; 2];
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0606`.
diff --git a/src/test/ui/array-slice-vec/vector-no-ann-2.rs b/src/test/ui/array-slice-vec/vector-no-ann-2.rs
new file mode 100644
index 000000000..e2055f551
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vector-no-ann-2.rs
@@ -0,0 +1,7 @@
+// run-pass
+
+// pretty-expanded FIXME #23616
+
+pub fn main() {
+ let _quux: Box<Vec<usize>> = Box::new(Vec::new());
+}
diff --git a/src/test/ui/array-slice-vec/vector-no-ann.rs b/src/test/ui/array-slice-vec/vector-no-ann.rs
new file mode 100644
index 000000000..1f11d9c8d
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vector-no-ann.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let _foo = Vec::new();
+ //~^ ERROR type annotations needed
+}
diff --git a/src/test/ui/array-slice-vec/vector-no-ann.stderr b/src/test/ui/array-slice-vec/vector-no-ann.stderr
new file mode 100644
index 000000000..d2ea08aa4
--- /dev/null
+++ b/src/test/ui/array-slice-vec/vector-no-ann.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed for `Vec<T>`
+ --> $DIR/vector-no-ann.rs:2:9
+ |
+LL | let _foo = Vec::new();
+ | ^^^^
+ |
+help: consider giving `_foo` an explicit type, where the type for type parameter `T` is specified
+ |
+LL | let _foo: Vec<T> = Vec::new();
+ | ++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.