about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/mir-opt/uniform_array_move_out.rs2
-rw-r--r--src/test/ui/array-slice-vec/vec-matching-fold.rs4
-rw-r--r--src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs2
-rw-r--r--src/test/ui/array-slice-vec/vec-matching.rs27
-rw-r--r--src/test/ui/array-slice-vec/vec-tail-matching.rs4
-rw-r--r--src/test/ui/associated-path-shl.rs1
-rw-r--r--src/test/ui/associated-path-shl.stderr16
-rw-r--r--src/test/ui/binding/irrefutable-slice-patterns.rs2
-rw-r--r--src/test/ui/binding/zero_sized_subslice_match.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr16
-rw-r--r--src/test/ui/borrowck/borrowck-describe-lvalue.rs8
-rw-r--r--src/test/ui/borrowck/borrowck-describe-lvalue.stderr16
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-from-array.stderr4
-rw-r--r--src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs12
-rw-r--r--src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr16
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs6
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr4
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr4
-rw-r--r--src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs2
-rw-r--r--src/test/ui/borrowck/return-local-binding-from-desugaring.rs33
-rw-r--r--src/test/ui/borrowck/return-local-binding-from-desugaring.stderr12
-rw-r--r--src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs40
-rw-r--r--src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs43
-rw-r--r--src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr48
-rw-r--r--src/test/ui/drop/dynamic-drop-async.rs4
-rw-r--r--src/test/ui/drop/dynamic-drop.rs6
-rw-r--r--src/test/ui/error-codes/E0528.rs2
-rw-r--r--src/test/ui/error-codes/E0528.stderr4
-rw-r--r--src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs4
-rw-r--r--src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr20
-rw-r--r--src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs5
-rw-r--r--src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr27
-rw-r--r--src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs5
-rw-r--r--src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr31
-rw-r--r--src/test/ui/feature-gates/feature-gate-slice-patterns.rs12
-rw-r--r--src/test/ui/feature-gates/feature-gate-slice-patterns.stderr24
-rw-r--r--src/test/ui/issues/issue-12369.rs4
-rw-r--r--src/test/ui/issues/issue-12369.stderr4
-rw-r--r--src/test/ui/issues/issue-15080.rs4
-rw-r--r--src/test/ui/issues/issue-15104.rs2
-rw-r--r--src/test/ui/issues/issue-17877.rs4
-rw-r--r--src/test/ui/issues/issue-26158.rs6
-rw-r--r--src/test/ui/issues/issue-26158.stderr9
-rw-r--r--src/test/ui/issues/issue-37598.rs5
-rw-r--r--src/test/ui/issues/issue-7784.rs2
-rw-r--r--src/test/ui/match/issue-50900.rs19
-rw-r--r--src/test/ui/match/issue-50900.stderr14
-rw-r--r--src/test/ui/match/match-vec-mismatch.rs4
-rw-r--r--src/test/ui/match/match-vec-mismatch.stderr4
-rw-r--r--src/test/ui/match/match-vec-unreachable.rs2
-rw-r--r--src/test/ui/non-exhaustive/non-exhaustive-match.rs14
-rw-r--r--src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs2
-rw-r--r--src/test/ui/parser/match-vec-invalid.rs10
-rw-r--r--src/test/ui/parser/match-vec-invalid.stderr47
-rw-r--r--src/test/ui/parser/pat-lt-bracket-6.rs6
-rw-r--r--src/test/ui/parser/pat-lt-bracket-6.stderr24
-rw-r--r--src/test/ui/parser/pat-lt-bracket-7.rs7
-rw-r--r--src/test/ui/parser/pat-lt-bracket-7.stderr16
-rw-r--r--src/test/ui/parser/pat-tuple-2.rs3
-rw-r--r--src/test/ui/parser/pat-tuple-2.stderr8
-rw-r--r--src/test/ui/parser/pat-tuple-3.rs2
-rw-r--r--src/test/ui/parser/pat-tuple-3.stderr6
-rw-r--r--src/test/ui/parser/pat-tuple-4.rs8
-rw-r--r--src/test/ui/parser/pat-tuple-4.stderr30
-rw-r--r--src/test/ui/parser/pat-tuple-5.rs7
-rw-r--r--src/test/ui/parser/pat-tuple-5.stderr32
-rw-r--r--src/test/ui/parser/recover-range-pats.rs123
-rw-r--r--src/test/ui/parser/recover-range-pats.stderr538
-rw-r--r--src/test/ui/parser/recover-tuple-pat.rs4
-rw-r--r--src/test/ui/parser/recover-tuple-pat.stderr20
-rw-r--r--src/test/ui/rfc-2005-default-binding-mode/slice.rs2
-rw-r--r--src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs2
-rw-r--r--src/test/ui/trailing-comma.rs2
79 files changed, 1240 insertions, 236 deletions
diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs
index fac5ef3b03c..c249154c71e 100644
--- a/src/test/mir-opt/uniform_array_move_out.rs
+++ b/src/test/mir-opt/uniform_array_move_out.rs
@@ -8,7 +8,7 @@ fn move_out_from_end() {
 
 fn move_out_by_subslice() {
     let a = [box 1, box 2];
-    let [_y..] = a;
+    let [_y @ ..] = a;
 }
 
 fn main() {
diff --git a/src/test/ui/array-slice-vec/vec-matching-fold.rs b/src/test/ui/array-slice-vec/vec-matching-fold.rs
index 2b19c49c427..f416160db24 100644
--- a/src/test/ui/array-slice-vec/vec-matching-fold.rs
+++ b/src/test/ui/array-slice-vec/vec-matching-fold.rs
@@ -11,7 +11,7 @@ fn foldl<T, U, F>(values: &[T],
     U: Clone+Debug, T:Debug,
     F: FnMut(U, &T) -> U,
 {    match values {
-        &[ref head, ref tail..] =>
+        &[ref head, ref tail @ ..] =>
             foldl(tail, function(initial, head), function),
         &[] => {
             // FIXME: call guards
@@ -28,7 +28,7 @@ fn foldr<T, U, F>(values: &[T],
     F: FnMut(&T, U) -> U,
 {
     match values {
-        &[ref head.., ref tail] =>
+        &[ref head @ .., ref tail] =>
             foldr(head, function(tail, initial), function),
         &[] => {
             // FIXME: call guards
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
index bce03b3375e..f0602c328b0 100644
--- 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
@@ -8,7 +8,7 @@ pub fn main() {
     let x: &[isize] = &[1, 2, 3, 4, 5];
     if !x.is_empty() {
         let el = match x {
-            &[1, ref tail..] => &tail[0],
+            &[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
index a37c25160fa..49c736bd728 100644
--- a/src/test/ui/array-slice-vec/vec-matching.rs
+++ b/src/test/ui/array-slice-vec/vec-matching.rs
@@ -14,7 +14,7 @@ fn a() {
 fn b() {
     let x = [1, 2, 3];
     match x {
-        [a, b, c..] => {
+        [a, b, c @ ..] => {
             assert_eq!(a, 1);
             assert_eq!(b, 2);
             let expected: &[_] = &[3];
@@ -22,7 +22,7 @@ fn b() {
         }
     }
     match x {
-        [a.., b, c] => {
+        [a @ .., b, c] => {
             let expected: &[_] = &[1];
             assert_eq!(a, expected);
             assert_eq!(b, 2);
@@ -30,7 +30,7 @@ fn b() {
         }
     }
     match x {
-        [a, b.., c] => {
+        [a, b @ .., c] => {
             assert_eq!(a, 1);
             let expected: &[_] = &[2];
             assert_eq!(b, expected);
@@ -50,7 +50,7 @@ fn b() {
 fn b_slice() {
     let x : &[_] = &[1, 2, 3];
     match x {
-        &[a, b, ref c..] => {
+        &[a, b, ref c @ ..] => {
             assert_eq!(a, 1);
             assert_eq!(b, 2);
             let expected: &[_] = &[3];
@@ -59,7 +59,7 @@ fn b_slice() {
         _ => unreachable!()
     }
     match x {
-        &[ref a.., b, c] => {
+        &[ref a @ .., b, c] => {
             let expected: &[_] = &[1];
             assert_eq!(a, expected);
             assert_eq!(b, 2);
@@ -68,7 +68,7 @@ fn b_slice() {
         _ => unreachable!()
     }
     match x {
-        &[a, ref b.., c] => {
+        &[a, ref b @ .., c] => {
             assert_eq!(a, 1);
             let expected: &[_] = &[2];
             assert_eq!(b, expected);
@@ -134,20 +134,6 @@ fn e() {
     assert_eq!(c, 1);
 }
 
-fn f() {
-    let x = &[1, 2, 3, 4, 5];
-    let [a, [b, [c, ..].., d].., e] = *x;
-    assert_eq!((a, b, c, d, e), (1, 2, 3, 4, 5));
-
-    let x: &[isize] = x;
-    let (a, b, c, d, e) = match *x {
-        [a, [b, [c, ..].., d].., e] => (a, b, c, d, e),
-        _ => unimplemented!()
-    };
-
-    assert_eq!((a, b, c, d, e), (1, 2, 3, 4, 5));
-}
-
 pub fn main() {
     a();
     b();
@@ -155,5 +141,4 @@ pub fn main() {
     c();
     d();
     e();
-    f();
 }
diff --git a/src/test/ui/array-slice-vec/vec-tail-matching.rs b/src/test/ui/array-slice-vec/vec-tail-matching.rs
index 84d246dff82..3c7b160dcc5 100644
--- a/src/test/ui/array-slice-vec/vec-tail-matching.rs
+++ b/src/test/ui/array-slice-vec/vec-tail-matching.rs
@@ -13,14 +13,14 @@ pub fn main() {
         Foo { string: "baz" }
     ];
     match x {
-        [ref first, ref tail..] => {
+        [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..] => {
+                [Foo { .. }, _, Foo { .. }, ref _tail @ ..] => {
                     unreachable!();
                 }
                 [Foo { string: ref a }, Foo { string: ref b }] => {
diff --git a/src/test/ui/associated-path-shl.rs b/src/test/ui/associated-path-shl.rs
index d159082ab7a..20a6fd83faa 100644
--- a/src/test/ui/associated-path-shl.rs
+++ b/src/test/ui/associated-path-shl.rs
@@ -5,6 +5,5 @@ fn main() {
     let _ = <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
     let <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
     let 0 ..= <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
-                           //~^ ERROR only char and numeric types are allowed in range patterns
     <<A>::B>::C; //~ ERROR cannot find type `A` in this scope
 }
diff --git a/src/test/ui/associated-path-shl.stderr b/src/test/ui/associated-path-shl.stderr
index 23918ed2e39..71ee93f4835 100644
--- a/src/test/ui/associated-path-shl.stderr
+++ b/src/test/ui/associated-path-shl.stderr
@@ -23,21 +23,11 @@ LL |     let 0 ..= <<A>::B>::C;
    |                 ^ not found in this scope
 
 error[E0412]: cannot find type `A` in this scope
-  --> $DIR/associated-path-shl.rs:9:7
+  --> $DIR/associated-path-shl.rs:8:7
    |
 LL |     <<A>::B>::C;
    |       ^ not found in this scope
 
-error[E0029]: only char and numeric types are allowed in range patterns
-  --> $DIR/associated-path-shl.rs:7:15
-   |
-LL |     let 0 ..= <<A>::B>::C;
-   |               ^^^^^^^^^^^ ranges require char or numeric types
-   |
-   = note: start type: {integer}
-   = note: end type: [type error]
-
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0029, E0412.
-For more information about an error, try `rustc --explain E0029`.
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/binding/irrefutable-slice-patterns.rs b/src/test/ui/binding/irrefutable-slice-patterns.rs
index 733e6b7b57f..ac733ef6e9c 100644
--- a/src/test/ui/binding/irrefutable-slice-patterns.rs
+++ b/src/test/ui/binding/irrefutable-slice-patterns.rs
@@ -4,7 +4,7 @@
 #![feature(slice_patterns)]
 
 fn foo(s: &[i32]) -> &[i32] {
-    let &[ref xs..] = s;
+    let &[ref xs @ ..] = s;
     xs
 }
 
diff --git a/src/test/ui/binding/zero_sized_subslice_match.rs b/src/test/ui/binding/zero_sized_subslice_match.rs
index 51e1c024bff..5326fa612a8 100644
--- a/src/test/ui/binding/zero_sized_subslice_match.rs
+++ b/src/test/ui/binding/zero_sized_subslice_match.rs
@@ -7,6 +7,6 @@ fn main() {
     // The subslice used to go out of bounds for zero-sized array items, check that this doesn't
     // happen anymore
     match x {
-        [_, ref y..] => assert_eq!(&x[1] as *const (), &y[0] as *const ())
+        [_, ref y @ ..] => assert_eq!(&x[1] as *const (), &y[0] as *const ())
     }
 }
diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr
index f1e1ae18839..20f05353d46 100644
--- a/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-describe-lvalue.nll.stderr
@@ -192,8 +192,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
 LL |         let x = &mut v;
    |                 ------ borrow of `v` occurs here
 LL |         match v {
-LL |             &[x..] => println!("{:?}", x),
-   |               ^ use of borrowed `v`
+LL |             &[x @ ..] => println!("{:?}", x),
+   |               ^^^^^^ use of borrowed `v`
 ...
 LL |         drop(x);
    |              - borrow later used here
@@ -204,8 +204,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
 LL |         let x = &mut v;
    |                 ------ borrow of `v` occurs here
 ...
-LL |             &[_, x..] => println!("{:?}", x),
-   |                  ^ use of borrowed `v`
+LL |             &[_, x @ ..] => println!("{:?}", x),
+   |                  ^^^^^^ use of borrowed `v`
 ...
 LL |         drop(x);
    |              - borrow later used here
@@ -216,8 +216,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
 LL |         let x = &mut v;
    |                 ------ borrow of `v` occurs here
 ...
-LL |             &[x.., _] => println!("{:?}", x),
-   |               ^ use of borrowed `v`
+LL |             &[x @ .., _] => println!("{:?}", x),
+   |               ^^^^^^ use of borrowed `v`
 ...
 LL |         drop(x);
    |              - borrow later used here
@@ -228,8 +228,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
 LL |         let x = &mut v;
    |                 ------ borrow of `v` occurs here
 ...
-LL |             &[_, x.., _] => println!("{:?}", x),
-   |                  ^ use of borrowed `v`
+LL |             &[_, x @ .., _] => println!("{:?}", x),
+   |                  ^^^^^^ use of borrowed `v`
 ...
 LL |         drop(x);
    |              - borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.rs b/src/test/ui/borrowck/borrowck-describe-lvalue.rs
index c8dbf4e6918..c27d9519dc7 100644
--- a/src/test/ui/borrowck/borrowck-describe-lvalue.rs
+++ b/src/test/ui/borrowck/borrowck-describe-lvalue.rs
@@ -140,22 +140,22 @@ fn main() {
         let mut v = &[1, 2, 3, 4, 5];
         let x = &mut v;
         match v {
-            &[x..] => println!("{:?}", x),
+            &[x @ ..] => println!("{:?}", x),
                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
             _ => panic!("other case"),
         }
         match v {
-            &[_, x..] => println!("{:?}", x),
+            &[_, x @ ..] => println!("{:?}", x),
                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
             _ => panic!("other case"),
         }
         match v {
-            &[x.., _] => println!("{:?}", x),
+            &[x @ .., _] => println!("{:?}", x),
                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
             _ => panic!("other case"),
         }
         match v {
-            &[_, x.., _] => println!("{:?}", x),
+            &[_, x @ .., _] => println!("{:?}", x),
                 //~^ ERROR cannot use `v[..]` because it was mutably borrowed
             _ => panic!("other case"),
         }
diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr
index 14b9b50f0c3..38d847a90ff 100644
--- a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr
+++ b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr
@@ -192,8 +192,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
 LL |         let x = &mut v;
    |                 ------ borrow of `v` occurs here
 LL |         match v {
-LL |             &[x..] => println!("{:?}", x),
-   |               ^ use of borrowed `v`
+LL |             &[x @ ..] => println!("{:?}", x),
+   |               ^^^^^^ use of borrowed `v`
 ...
 LL |         drop(x);
    |              - borrow later used here
@@ -204,8 +204,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
 LL |         let x = &mut v;
    |                 ------ borrow of `v` occurs here
 ...
-LL |             &[_, x..] => println!("{:?}", x),
-   |                  ^ use of borrowed `v`
+LL |             &[_, x @ ..] => println!("{:?}", x),
+   |                  ^^^^^^ use of borrowed `v`
 ...
 LL |         drop(x);
    |              - borrow later used here
@@ -216,8 +216,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
 LL |         let x = &mut v;
    |                 ------ borrow of `v` occurs here
 ...
-LL |             &[x.., _] => println!("{:?}", x),
-   |               ^ use of borrowed `v`
+LL |             &[x @ .., _] => println!("{:?}", x),
+   |               ^^^^^^ use of borrowed `v`
 ...
 LL |         drop(x);
    |              - borrow later used here
@@ -228,8 +228,8 @@ error[E0503]: cannot use `v[..]` because it was mutably borrowed
 LL |         let x = &mut v;
    |                 ------ borrow of `v` occurs here
 ...
-LL |             &[_, x.., _] => println!("{:?}", x),
-   |                  ^ use of borrowed `v`
+LL |             &[_, x @ .., _] => println!("{:?}", x),
+   |                  ^^^^^^ use of borrowed `v`
 ...
 LL |         drop(x);
    |              - borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.rs b/src/test/ui/borrowck/borrowck-move-out-from-array.rs
index 856b03edd2d..ee6abf407a3 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array.rs
@@ -10,7 +10,7 @@ fn move_out_from_begin_and_end() {
 fn move_out_by_const_index_and_subslice() {
     let a = [box 1, box 2];
     let [_x, _] = a;
-    let [_y..] = a; //~ ERROR [E0382]
+    let [_y @ ..] = a; //~ ERROR [E0382]
 }
 
 fn main() {}
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
index 16722a456de..b34c03e6def 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr
@@ -13,8 +13,8 @@ error[E0382]: use of moved value: `a[..]`
    |
 LL |     let [_x, _] = a;
    |          -- value moved here
-LL |     let [_y..] = a;
-   |          ^^ value used here after move
+LL |     let [_y @ ..] = a;
+   |          ^^^^^^^ value used here after move
    |
    = note: move occurs because `a[..]` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
 
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs
index cc524c1ac3e..fa9a3c217db 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs
+++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs
@@ -15,7 +15,7 @@ pub fn main() {
     ];
     let x: &[Foo] = &x;
     match *x {
-        [_, ref tail..] => {
+        [_, ref tail @ ..] => {
             match tail {
             //~^ ERROR cannot move out of type `[Foo]`
                 &[Foo { string: a },
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs
index 7675147c8ec..048813b2b93 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs
@@ -5,7 +5,7 @@
 
 fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> {
     match *v {
-        [ref mut head, ref mut tail..] => {
+        [ref mut head, ref mut tail @ ..] => {
             Some((head, tail))
         }
         [] => None
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs
index 5de8dd3305e..a6b54f9537d 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.rs
@@ -70,7 +70,7 @@ fn const_index_mixed(s: &mut [i32]) {
 
 fn const_index_and_subslice_ok(s: &mut [i32]) {
     if let [ref first, ref second, ..] = *s {
-        if let [_, _, ref mut tail..] = *s {
+        if let [_, _, ref mut tail @ ..] = *s {
             nop(&[first, second]);
             nop_subslice(tail);
         }
@@ -79,7 +79,7 @@ fn const_index_and_subslice_ok(s: &mut [i32]) {
 
 fn const_index_and_subslice_err(s: &mut [i32]) {
     if let [ref first, ref second, ..] = *s {
-        if let [_, ref mut tail..] = *s { //~ERROR
+        if let [_, ref mut tail @ ..] = *s { //~ERROR
             nop(&[first, second]);
             nop_subslice(tail);
         }
@@ -88,7 +88,7 @@ fn const_index_and_subslice_err(s: &mut [i32]) {
 
 fn const_index_and_subslice_from_end_ok(s: &mut [i32]) {
     if let [.., ref second, ref first] = *s {
-        if let [ref mut tail.., _, _] = *s {
+        if let [ref mut tail @ .., _, _] = *s {
             nop(&[first, second]);
             nop_subslice(tail);
         }
@@ -97,7 +97,7 @@ fn const_index_and_subslice_from_end_ok(s: &mut [i32]) {
 
 fn const_index_and_subslice_from_end_err(s: &mut [i32]) {
     if let [.., ref second, ref first] = *s {
-        if let [ref mut tail.., _] = *s { //~ERROR
+        if let [ref mut tail @ .., _] = *s { //~ERROR
             nop(&[first, second]);
             nop_subslice(tail);
         }
@@ -105,8 +105,8 @@ fn const_index_and_subslice_from_end_err(s: &mut [i32]) {
 }
 
 fn subslices(s: &mut [i32]) {
-    if let [_, _, _, ref s1..] = *s {
-        if let [ref mut s2.., _, _, _] = *s { //~ERROR
+    if let [_, _, _, ref s1 @ ..] = *s {
+        if let [ref mut s2 @ .., _, _, _] = *s { //~ERROR
             nop_subslice(s1);
             nop_subslice(s2);
         }
diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr
index f716ee68b00..2c019f44611 100644
--- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr
+++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr
@@ -89,8 +89,8 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im
    |
 LL |     if let [ref first, ref second, ..] = *s {
    |                        ---------- immutable borrow occurs here
-LL |         if let [_, ref mut tail..] = *s {
-   |                    ^^^^^^^^^^^^ mutable borrow occurs here
+LL |         if let [_, ref mut tail @ ..] = *s {
+   |                    ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
 LL |             nop(&[first, second]);
    |                          ------ immutable borrow later used here
 
@@ -99,18 +99,18 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im
    |
 LL |     if let [.., ref second, ref first] = *s {
    |                 ---------- immutable borrow occurs here
-LL |         if let [ref mut tail.., _] = *s {
-   |                 ^^^^^^^^^^^^ mutable borrow occurs here
+LL |         if let [ref mut tail @ .., _] = *s {
+   |                 ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
 LL |             nop(&[first, second]);
    |                          ------ immutable borrow later used here
 
 error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
   --> $DIR/borrowck-slice-pattern-element-loan.rs:109:17
    |
-LL |     if let [_, _, _, ref s1..] = *s {
-   |                      ------ immutable borrow occurs here
-LL |         if let [ref mut s2.., _, _, _] = *s {
-   |                 ^^^^^^^^^^ mutable borrow occurs here
+LL |     if let [_, _, _, ref s1 @ ..] = *s {
+   |                      ----------- immutable borrow occurs here
+LL |         if let [ref mut s2 @ .., _, _, _] = *s {
+   |                 ^^^^^^^^^^^^^^^ mutable borrow occurs here
 LL |             nop_subslice(s1);
    |                          -- immutable borrow later used here
 
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs
index 100384d78c8..53a9bcef74a 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs
@@ -4,7 +4,7 @@ fn a<'a>() -> &'a [isize] {
     let vec = vec![1, 2, 3, 4];
     let vec: &[isize] = &vec;
     let tail = match vec {
-        &[_, ref tail..] => tail,
+        &[_, ref tail @ ..] => tail,
         _ => panic!("a")
     };
     tail //~ ERROR cannot return value referencing local variable `vec`
@@ -14,7 +14,7 @@ fn b<'a>() -> &'a [isize] {
     let vec = vec![1, 2, 3, 4];
     let vec: &[isize] = &vec;
     let init = match vec {
-        &[ref init.., _] => init,
+        &[ref init @ .., _] => init,
         _ => panic!("b")
     };
     init //~ ERROR cannot return value referencing local variable `vec`
@@ -24,7 +24,7 @@ fn c<'a>() -> &'a [isize] {
     let vec = vec![1, 2, 3, 4];
     let vec: &[isize] = &vec;
     let slice = match vec {
-        &[_, ref slice.., _] => slice,
+        &[_, ref slice @ .., _] => slice,
         _ => panic!("c")
     };
     slice //~ ERROR cannot return value referencing local variable `vec`
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs
index 4d99a92b18b..dd9023f6d9f 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs
@@ -4,7 +4,7 @@ fn a() {
     let mut v = vec![1, 2, 3];
     let vb: &mut [isize] = &mut v;
     match vb {
-        &mut [_a, ref tail..] => {
+        &mut [_a, ref tail @ ..] => {
             v.push(tail[0] + tail[1]); //~ ERROR cannot borrow
         }
         _ => {}
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs
index efc52530716..420223009a4 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs
@@ -5,7 +5,7 @@
 fn main() {
     let mut a = [1, 2, 3, 4];
     let t = match a {
-        [1, 2, ref tail..] => tail,
+        [1, 2, ref tail @ ..] => tail,
         _ => unreachable!()
     };
     println!("t[0]: {}", t[0]);
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
index b2f553ba49f..9f8e6fe3b68 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr
@@ -1,8 +1,8 @@
 error[E0506]: cannot assign to `a[_]` because it is borrowed
   --> $DIR/borrowck-vec-pattern-move-tail.rs:12:5
    |
-LL |         [1, 2, ref tail..] => tail,
-   |                -------- borrow of `a[_]` occurs here
+LL |         [1, 2, ref tail @ ..] => tail,
+   |                ------------- borrow of `a[_]` occurs here
 ...
 LL |     a[2] = 0;
    |     ^^^^^^^^ assignment to borrowed `a[_]` occurs here
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
index 6448149391d..a215305f684 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
@@ -19,7 +19,7 @@ fn b() {
     let mut vec = vec![box 1, box 2, box 3];
     let vec: &mut [Box<isize>] = &mut vec;
     match vec {
-        &mut [ref _b..] => {
+        &mut [ref _b @ ..] => {
         //~^ borrow of `vec[_]` occurs here
             vec[0] = box 4; //~ ERROR cannot assign
             //~^ NOTE assignment to borrowed `vec[_]` occurs here
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
index 072501f23ff..f54a3a4072c 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
@@ -13,8 +13,8 @@ LL |             _a.use_ref();
 error[E0506]: cannot assign to `vec[_]` because it is borrowed
   --> $DIR/borrowck-vec-pattern-nesting.rs:24:13
    |
-LL |         &mut [ref _b..] => {
-   |               ------ borrow of `vec[_]` occurs here
+LL |         &mut [ref _b @ ..] => {
+   |               ----------- borrow of `vec[_]` occurs here
 LL |
 LL |             vec[0] = box 4;
    |             ^^^^^^ assignment to borrowed `vec[_]` occurs here
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs
index e602e75886d..c35be2f6be6 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs
@@ -4,7 +4,7 @@ fn a<'a>() -> &'a isize {
     let vec = vec![1, 2, 3, 4];
     let vec: &[isize] = &vec;
     let tail = match vec {
-        &[_a, ref tail..] => &tail[0],
+        &[_a, ref tail @ ..] => &tail[0],
         _ => panic!("foo")
     };
     tail //~ ERROR cannot return value referencing local variable `vec`
diff --git a/src/test/ui/borrowck/return-local-binding-from-desugaring.rs b/src/test/ui/borrowck/return-local-binding-from-desugaring.rs
new file mode 100644
index 00000000000..b2dcd54ec2e
--- /dev/null
+++ b/src/test/ui/borrowck/return-local-binding-from-desugaring.rs
@@ -0,0 +1,33 @@
+// To avoid leaking the names of local bindings from expressions like for loops, #60984
+// explicitly ignored them, but an assertion that `LocalKind::Var` *must* have a name would
+// trigger an ICE. Before this change, this file's output would be:
+// ```
+// error[E0515]: cannot return value referencing local variable `__next`
+//   --> return-local-binding-from-desugaring.rs:LL:CC
+//    |
+// LL |     for ref x in xs {
+//    |         ----- `__next` is borrowed here
+// ...
+// LL |     result
+//    |     ^^^^^^ returns a value referencing data owned by the current function
+// ```
+// FIXME: ideally `LocalKind` would carry more information to more accurately explain the problem.
+
+use std::collections::HashMap;
+use std::hash::Hash;
+
+fn group_by<I, F, T>(xs: &mut I, f: F) -> HashMap<T, Vec<&I::Item>>
+where
+    I: Iterator,
+    F: Fn(&I::Item) -> T,
+    T: Eq + Hash,
+{
+    let mut result = HashMap::new();
+    for ref x in xs {
+        let key = f(x);
+        result.entry(key).or_insert(Vec::new()).push(x);
+    }
+    result //~ ERROR cannot return value referencing local binding
+}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/return-local-binding-from-desugaring.stderr b/src/test/ui/borrowck/return-local-binding-from-desugaring.stderr
new file mode 100644
index 00000000000..293dbe62813
--- /dev/null
+++ b/src/test/ui/borrowck/return-local-binding-from-desugaring.stderr
@@ -0,0 +1,12 @@
+error[E0515]: cannot return value referencing local binding
+  --> $DIR/return-local-binding-from-desugaring.rs:30:5
+   |
+LL |     for ref x in xs {
+   |                  -- local binding introduced here
+...
+LL |     result
+   |     ^^^^^^ returns a value referencing data owned by the current function
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0515`.
diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs
new file mode 100644
index 00000000000..db941a440e1
--- /dev/null
+++ b/src/test/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs
@@ -0,0 +1,40 @@
+// check-pass
+
+pub fn yes_vec_partial_eq_array<A, B>() -> impl PartialEq<[B; 32]>
+where
+    A: PartialEq<B>,
+{
+    Vec::<A>::new()
+}
+
+pub fn yes_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]>
+where
+    A: PartialEq<B>,
+{
+    Vec::<A>::new()
+}
+
+use std::collections::VecDeque;
+
+pub fn yes_vecdeque_partial_eq_array<A, B>() -> impl PartialEq<[B; 32]>
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+pub fn yes_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]>
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+pub fn yes_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 32]>
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs
new file mode 100644
index 00000000000..19107e6bf16
--- /dev/null
+++ b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.rs
@@ -0,0 +1,43 @@
+pub fn no_vec_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    Vec::<A>::new()
+}
+
+pub fn no_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    Vec::<A>::new()
+}
+
+use std::collections::VecDeque;
+
+pub fn no_vecdeque_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+pub fn no_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+pub fn no_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]>
+//~^ ERROR arrays only have std trait implementations for lengths 0..=32
+where
+    A: PartialEq<B>,
+{
+    VecDeque::<A>::new()
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr
new file mode 100644
index 00000000000..5c37468130c
--- /dev/null
+++ b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr
@@ -0,0 +1,48 @@
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:1:43
+   |
+LL | pub fn no_vec_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::vec::Vec<A>`
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:9:51
+   |
+LL | pub fn no_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
+   |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::vec::Vec<A>`
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:19:48
+   |
+LL | pub fn no_vecdeque_partial_eq_array<A, B>() -> impl PartialEq<[B; 33]>
+   |                                                ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::collections::VecDeque<A>`
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:27:56
+   |
+LL | pub fn no_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]>
+   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::collections::VecDeque<A>`
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: arrays only have std trait implementations for lengths 0..=32
+  --> $DIR/alloc-traits-no-impls-length-33.rs:35:60
+   |
+LL | pub fn no_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]>
+   |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]`
+   |
+   = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a mut [B; 33]>` for `std::collections::VecDeque<A>`
+   = note: the return type of a function must have a statically known size
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs
index 9226145d935..f3f5c382275 100644
--- a/src/test/ui/drop/dynamic-drop-async.rs
+++ b/src/test/ui/drop/dynamic-drop-async.rs
@@ -217,7 +217,7 @@ async fn subslice_pattern_from_end_with_drop(a: Rc<Allocator>, arg: bool, arg2:
     if arg {
         let [.., _x, _] = arr;
     } else {
-        let [_, _y..] = arr;
+        let [_, _y @ ..] = arr;
     }
     a.alloc().await;
 }
@@ -226,7 +226,7 @@ async fn subslice_pattern_reassign(a: Rc<Allocator>) {
     let mut ar = [a.alloc().await, a.alloc().await, a.alloc().await];
     let [_, _, _x] = ar;
     ar = [a.alloc().await, a.alloc().await, a.alloc().await];
-    let [_, _y..] = ar;
+    let [_, _y @ ..] = ar;
     a.alloc().await;
 }
 
diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs
index eb1a3f3a9f9..8516bc3d964 100644
--- a/src/test/ui/drop/dynamic-drop.rs
+++ b/src/test/ui/drop/dynamic-drop.rs
@@ -237,7 +237,7 @@ fn subslice_pattern_from_end(a: &Allocator, arg: bool) {
     if arg {
         let[.., _x, _] = a;
     } else {
-        let[_, _y..] = a;
+        let[_, _y @ ..] = a;
     }
 }
 
@@ -251,7 +251,7 @@ fn subslice_pattern_from_end_with_drop(a: &Allocator, arg: bool, arg2: bool) {
     if arg {
         let[.., _x, _] = a;
     } else {
-        let[_, _y..] = a;
+        let[_, _y @ ..] = a;
     }
 }
 
@@ -266,7 +266,7 @@ fn subslice_pattern_reassign(a: &Allocator) {
     let mut ar = [a.alloc(), a.alloc(), a.alloc()];
     let[_, _, _x] = ar;
     ar = [a.alloc(), a.alloc(), a.alloc()];
-    let[_, _y..] = ar;
+    let[_, _y @ ..] = ar;
 }
 
 fn panic_after_return(a: &Allocator) -> Ptr<'_> {
diff --git a/src/test/ui/error-codes/E0528.rs b/src/test/ui/error-codes/E0528.rs
index f2681fa043d..17d03b14fc6 100644
--- a/src/test/ui/error-codes/E0528.rs
+++ b/src/test/ui/error-codes/E0528.rs
@@ -3,7 +3,7 @@
 fn main() {
     let r = &[1, 2];
     match r {
-        &[a, b, c, rest..] => {
+        &[a, b, c, rest @ ..] => {
         //~^ ERROR E0528
         }
     }
diff --git a/src/test/ui/error-codes/E0528.stderr b/src/test/ui/error-codes/E0528.stderr
index a7205af5054..0f566091145 100644
--- a/src/test/ui/error-codes/E0528.stderr
+++ b/src/test/ui/error-codes/E0528.stderr
@@ -1,8 +1,8 @@
 error[E0528]: pattern requires at least 3 elements but array has 2
   --> $DIR/E0528.rs:6:10
    |
-LL |         &[a, b, c, rest..] => {
-   |          ^^^^^^^^^^^^^^^^^ pattern cannot match array of 2 elements
+LL |         &[a, b, c, rest @ ..] => {
+   |          ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 2 elements
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs
index d95c4b09994..d97b693f520 100644
--- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs
+++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.rs
@@ -2,7 +2,9 @@
 
 fn main() {
     match [5..4, 99..105, 43..44] {
-        [_, 99.., _] => {}, //~ ERROR unexpected token: `,`
+        [_, 99.., _] => {},
+        //~^ ERROR `X..` range patterns are not supported
+        //~| ERROR mismatched types
         _ => {},
     }
 }
diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr
index 359725a41c1..4ecd8515ee1 100644
--- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr
+++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr
@@ -1,8 +1,20 @@
-error: unexpected token: `,`
-  --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:17
+error: `X..` range patterns are not supported
+  --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13
    |
 LL |         [_, 99.., _] => {},
-   |                 ^
+   |             ^^^^ help: try using the maximum value for the type: `99..MAX`
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13
+   |
+LL |     match [5..4, 99..105, 43..44] {
+   |           ----------------------- this match expression has type `std::ops::Range<{integer}>`
+LL |         [_, 99.., _] => {},
+   |             ^^^^ expected struct `std::ops::Range`, found integer
+   |
+   = note: expected type `std::ops::Range<{integer}>`
+              found type `{integer}`
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs
index 95677e34dd7..09f459c9862 100644
--- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs
+++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.rs
@@ -2,7 +2,10 @@
 
 fn main() {
     match [5..4, 99..105, 43..44] {
-        [_, 99..] => {}, //~ ERROR unexpected token: `]`
+        [_, 99..] => {},
+        //~^ ERROR `X..` range patterns are not supported
+        //~| ERROR pattern requires 2 elements but array has 3
+        //~| ERROR mismatched types
         _ => {},
     }
 }
diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr
index 8f849d7b3f8..922d2692315 100644
--- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr
+++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr
@@ -1,8 +1,27 @@
-error: unexpected token: `]`
-  --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:17
+error: `X..` range patterns are not supported
+  --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13
    |
 LL |         [_, 99..] => {},
-   |                 ^
+   |             ^^^^ help: try using the maximum value for the type: `99..MAX`
 
-error: aborting due to previous error
+error[E0527]: pattern requires 2 elements but array has 3
+  --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:9
+   |
+LL |         [_, 99..] => {},
+   |         ^^^^^^^^^ expected 3 elements
+
+error[E0308]: mismatched types
+  --> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13
+   |
+LL |     match [5..4, 99..105, 43..44] {
+   |           ----------------------- this match expression has type `std::ops::Range<{integer}>`
+LL |         [_, 99..] => {},
+   |             ^^^^ expected struct `std::ops::Range`, found integer
+   |
+   = note: expected type `std::ops::Range<{integer}>`
+              found type `{integer}`
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0308, E0527.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs
index 3bf5da710ef..95e58b1d48c 100644
--- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs
+++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.rs
@@ -2,7 +2,10 @@
 
 fn main() {
     match [5..4, 99..105, 43..44] {
-        [..9, 99..100, _] => {}, //~ ERROR expected one of `,` or `]`, found `9`
+        [..9, 99..100, _] => {},
+        //~^ ERROR `..X` range patterns are not supported
+        //~| ERROR mismatched types
+        //~| ERROR mismatched types
         _ => {},
     }
 }
diff --git a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr
index a09ba3562e0..8907b875f8e 100644
--- a/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr
+++ b/src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr
@@ -1,8 +1,31 @@
-error: expected one of `,` or `]`, found `9`
-  --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12
+error: `..X` range patterns are not supported
+  --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10
    |
 LL |         [..9, 99..100, _] => {},
-   |            ^ expected one of `,` or `]` here
+   |          ^^^ help: try using the minimum value for the type: `MIN..9`
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:10
+   |
+LL |     match [5..4, 99..105, 43..44] {
+   |           ----------------------- this match expression has type `std::ops::Range<{integer}>`
+LL |         [..9, 99..100, _] => {},
+   |          ^^^ expected struct `std::ops::Range`, found integer
+   |
+   = note: expected type `std::ops::Range<{integer}>`
+              found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15
+   |
+LL |     match [5..4, 99..105, 43..44] {
+   |           ----------------------- this match expression has type `std::ops::Range<{integer}>`
+LL |         [..9, 99..100, _] => {},
+   |               ^^^^^^^ expected struct `std::ops::Range`, found integer
+   |
+   = note: expected type `std::ops::Range<{integer}>`
+              found type `{integer}`
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs
index 0165321debe..f2a1b135b69 100644
--- a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs
+++ b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs
@@ -3,15 +3,15 @@
 fn main() {
     let x = [1, 2, 3, 4, 5];
     match x {
-        [1, 2, ..] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
-        [1, .., 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
-        [.., 4, 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+        [1, 2, ..] => {} //~ ERROR subslice patterns are unstable
+        [1, .., 5] => {} //~ ERROR subslice patterns are unstable
+        [.., 4, 5] => {} //~ ERROR subslice patterns are unstable
     }
 
     let x = [ 1, 2, 3, 4, 5 ];
     match x {
-        [ xs.., 4, 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
-        [ 1, xs.., 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
-        [ 1, 2, xs.. ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized
+        [ xs @ .., 4, 5 ] => {} //~ ERROR subslice patterns are unstable
+        [ 1, xs @ .., 5 ] => {} //~ ERROR subslice patterns are unstable
+        [ 1, 2, xs @ .. ] => {} //~ ERROR subslice patterns are unstable
     }
 }
diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr
index e88fddaa81f..d4946a42b8f 100644
--- a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr
+++ b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr
@@ -1,4 +1,4 @@
-error[E0658]: syntax for subslices in slice patterns is not yet stabilized
+error[E0658]: subslice patterns are unstable
   --> $DIR/feature-gate-slice-patterns.rs:6:16
    |
 LL |         [1, 2, ..] => {}
@@ -7,7 +7,7 @@ LL |         [1, 2, ..] => {}
    = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
 
-error[E0658]: syntax for subslices in slice patterns is not yet stabilized
+error[E0658]: subslice patterns are unstable
   --> $DIR/feature-gate-slice-patterns.rs:7:13
    |
 LL |         [1, .., 5] => {}
@@ -16,7 +16,7 @@ LL |         [1, .., 5] => {}
    = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
 
-error[E0658]: syntax for subslices in slice patterns is not yet stabilized
+error[E0658]: subslice patterns are unstable
   --> $DIR/feature-gate-slice-patterns.rs:8:10
    |
 LL |         [.., 4, 5] => {}
@@ -25,29 +25,29 @@ LL |         [.., 4, 5] => {}
    = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
 
-error[E0658]: syntax for subslices in slice patterns is not yet stabilized
+error[E0658]: subslice patterns are unstable
   --> $DIR/feature-gate-slice-patterns.rs:13:11
    |
-LL |         [ xs.., 4, 5 ] => {}
-   |           ^^
+LL |         [ xs @ .., 4, 5 ] => {}
+   |           ^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
 
-error[E0658]: syntax for subslices in slice patterns is not yet stabilized
+error[E0658]: subslice patterns are unstable
   --> $DIR/feature-gate-slice-patterns.rs:14:14
    |
-LL |         [ 1, xs.., 5 ] => {}
-   |              ^^
+LL |         [ 1, xs @ .., 5 ] => {}
+   |              ^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
 
-error[E0658]: syntax for subslices in slice patterns is not yet stabilized
+error[E0658]: subslice patterns are unstable
   --> $DIR/feature-gate-slice-patterns.rs:15:17
    |
-LL |         [ 1, 2, xs.. ] => {}
-   |                 ^^
+LL |         [ 1, 2, xs @ .. ] => {}
+   |                 ^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/62254
    = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
diff --git a/src/test/ui/issues/issue-12369.rs b/src/test/ui/issues/issue-12369.rs
index 8df8efefd05..08661318074 100644
--- a/src/test/ui/issues/issue-12369.rs
+++ b/src/test/ui/issues/issue-12369.rs
@@ -6,7 +6,7 @@ fn main() {
     let v: isize = match &*sl {
         &[] => 0,
         &[a,b,c] => 3,
-        &[a, ref rest..] => a,
-        &[10,a, ref rest..] => 10 //~ ERROR: unreachable pattern
+        &[a, ref rest @ ..] => a,
+        &[10,a, ref rest @ ..] => 10 //~ ERROR: unreachable pattern
     };
 }
diff --git a/src/test/ui/issues/issue-12369.stderr b/src/test/ui/issues/issue-12369.stderr
index fec9078dc40..f27425e28c6 100644
--- a/src/test/ui/issues/issue-12369.stderr
+++ b/src/test/ui/issues/issue-12369.stderr
@@ -1,8 +1,8 @@
 error: unreachable pattern
   --> $DIR/issue-12369.rs:10:9
    |
-LL |         &[10,a, ref rest..] => 10
-   |         ^^^^^^^^^^^^^^^^^^^
+LL |         &[10,a, ref rest @ ..] => 10
+   |         ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: lint level defined here
   --> $DIR/issue-12369.rs:2:9
diff --git a/src/test/ui/issues/issue-15080.rs b/src/test/ui/issues/issue-15080.rs
index 4558118a809..b11b1cda38a 100644
--- a/src/test/ui/issues/issue-15080.rs
+++ b/src/test/ui/issues/issue-15080.rs
@@ -7,11 +7,11 @@ fn main() {
     let mut result = vec![];
     loop {
         x = match *x {
-            [1, n, 3, ref rest..] => {
+            [1, n, 3, ref rest @ ..] => {
                 result.push(n);
                 rest
             }
-            [n, ref rest..] => {
+            [n, ref rest @ ..] => {
                 result.push(n);
                 rest
             }
diff --git a/src/test/ui/issues/issue-15104.rs b/src/test/ui/issues/issue-15104.rs
index 3a03a52c324..ee977541137 100644
--- a/src/test/ui/issues/issue-15104.rs
+++ b/src/test/ui/issues/issue-15104.rs
@@ -9,6 +9,6 @@ fn count_members(v: &[usize]) -> usize {
     match *v {
         []         => 0,
         [_]        => 1,
-        [_, ref xs..] => 1 + count_members(xs)
+        [_, ref xs @ ..] => 1 + count_members(xs)
     }
 }
diff --git a/src/test/ui/issues/issue-17877.rs b/src/test/ui/issues/issue-17877.rs
index af22b1ad8f0..fefa3f2f873 100644
--- a/src/test/ui/issues/issue-17877.rs
+++ b/src/test/ui/issues/issue-17877.rs
@@ -7,8 +7,8 @@ fn main() {
     }, 42_usize);
 
     assert_eq!(match [0u8; 1024] {
-        [1, _..] => 0_usize,
-        [0, _..] => 1_usize,
+        [1, ..] => 0_usize,
+        [0, ..] => 1_usize,
         _ => 2_usize
     }, 1_usize);
 }
diff --git a/src/test/ui/issues/issue-26158.rs b/src/test/ui/issues/issue-26158.rs
deleted file mode 100644
index 11f47b6d02a..00000000000
--- a/src/test/ui/issues/issue-26158.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(slice_patterns)]
-
-fn main() {
-    let x: &[u32] = &[];
-    let &[[ref _a, ref _b..]..] = x; //~ ERROR refutable pattern
-}
diff --git a/src/test/ui/issues/issue-26158.stderr b/src/test/ui/issues/issue-26158.stderr
deleted file mode 100644
index 3a4dd79e810..00000000000
--- a/src/test/ui/issues/issue-26158.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0005]: refutable pattern in local binding: `&[]` not covered
-  --> $DIR/issue-26158.rs:5:9
-   |
-LL |     let &[[ref _a, ref _b..]..] = x;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ pattern `&[]` not covered
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0005`.
diff --git a/src/test/ui/issues/issue-37598.rs b/src/test/ui/issues/issue-37598.rs
index 1bec3d340d6..31b3aba6bc2 100644
--- a/src/test/ui/issues/issue-37598.rs
+++ b/src/test/ui/issues/issue-37598.rs
@@ -1,11 +1,10 @@
-// build-pass (FIXME(62277): could be check-pass?)
-#![allow(dead_code)]
+// check-pass
 #![feature(slice_patterns)]
 
 fn check(list: &[u8]) {
     match list {
         &[] => {},
-        &[_u1, _u2, ref _next..] => {},
+        &[_u1, _u2, ref _next @ ..] => {},
         &[_u1] => {},
     }
 }
diff --git a/src/test/ui/issues/issue-7784.rs b/src/test/ui/issues/issue-7784.rs
index b75e547079e..5b70bd6e5ff 100644
--- a/src/test/ui/issues/issue-7784.rs
+++ b/src/test/ui/issues/issue-7784.rs
@@ -24,7 +24,7 @@ fn main() {
     assert_eq!(d, "baz");
 
     let out = bar("baz", "foo");
-    let [a, xs.., d] = out;
+    let [a, xs @ .., d] = out;
     assert_eq!(a, "baz");
     assert_eq!(xs, ["foo", "foo"]);
     assert_eq!(d, "baz");
diff --git a/src/test/ui/match/issue-50900.rs b/src/test/ui/match/issue-50900.rs
new file mode 100644
index 00000000000..27135af9575
--- /dev/null
+++ b/src/test/ui/match/issue-50900.rs
@@ -0,0 +1,19 @@
+#[derive(PartialEq, Eq)]
+pub struct Tag(pub Context, pub u16);
+
+#[derive(PartialEq, Eq)]
+pub enum Context {
+    Tiff,
+    Exif,
+}
+
+impl Tag {
+    const ExifIFDPointer: Tag = Tag(Context::Tiff, 34665);
+}
+
+fn main() {
+    match Tag::ExifIFDPointer {
+    //~^ ERROR: non-exhaustive patterns: `Tag(Exif, _)` not covered
+        Tag::ExifIFDPointer => {}
+    }
+}
diff --git a/src/test/ui/match/issue-50900.stderr b/src/test/ui/match/issue-50900.stderr
new file mode 100644
index 00000000000..7192f11a5e8
--- /dev/null
+++ b/src/test/ui/match/issue-50900.stderr
@@ -0,0 +1,14 @@
+error[E0004]: non-exhaustive patterns: `Tag(Exif, _)` not covered
+  --> $DIR/issue-50900.rs:15:11
+   |
+LL | pub struct Tag(pub Context, pub u16);
+   | ------------------------------------- `Tag` defined here
+...
+LL |     match Tag::ExifIFDPointer {
+   |           ^^^^^^^^^^^^^^^^^^^ pattern `Tag(Exif, _)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/match/match-vec-mismatch.rs b/src/test/ui/match/match-vec-mismatch.rs
index 5e61c1b22a0..a0ef92743ac 100644
--- a/src/test/ui/match/match-vec-mismatch.rs
+++ b/src/test/ui/match/match-vec-mismatch.rs
@@ -19,10 +19,10 @@ fn main() {
     match [0, 1, 2] {
         [0] => {}, //~ ERROR pattern requires
 
-        [0, 1, x..] => {
+        [0, 1, x @ ..] => {
             let a: [_; 1] = x;
         }
-        [0, 1, 2, 3, x..] => {} //~ ERROR pattern requires
+        [0, 1, 2, 3, x @ ..] => {} //~ ERROR pattern requires
     };
 
     match does_not_exist { //~ ERROR cannot find value `does_not_exist` in this scope
diff --git a/src/test/ui/match/match-vec-mismatch.stderr b/src/test/ui/match/match-vec-mismatch.stderr
index 47f9d48e262..2f1bbb76216 100644
--- a/src/test/ui/match/match-vec-mismatch.stderr
+++ b/src/test/ui/match/match-vec-mismatch.stderr
@@ -19,8 +19,8 @@ LL |         [0] => {},
 error[E0528]: pattern requires at least 4 elements but array has 3
   --> $DIR/match-vec-mismatch.rs:25:9
    |
-LL |         [0, 1, 2, 3, x..] => {}
-   |         ^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements
+LL |         [0, 1, 2, 3, x @ ..] => {}
+   |         ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements
 
 error[E0282]: type annotations needed
   --> $DIR/match-vec-mismatch.rs:36:9
diff --git a/src/test/ui/match/match-vec-unreachable.rs b/src/test/ui/match/match-vec-unreachable.rs
index 9e167f37ba9..78810525bad 100644
--- a/src/test/ui/match/match-vec-unreachable.rs
+++ b/src/test/ui/match/match-vec-unreachable.rs
@@ -23,7 +23,7 @@ fn main() {
     let x: Vec<char> = vec!['a', 'b', 'c'];
     let x: &[char] = &x;
     match *x {
-        ['a', 'b', 'c', ref _tail..] => {}
+        ['a', 'b', 'c', ref _tail @ ..] => {}
         ['a', 'b', 'c'] => {} //~ ERROR unreachable pattern
         _ => {}
     }
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-match.rs b/src/test/ui/non-exhaustive/non-exhaustive-match.rs
index e888bcf5168..8cc5f4042cc 100644
--- a/src/test/ui/non-exhaustive/non-exhaustive-match.rs
+++ b/src/test/ui/non-exhaustive/non-exhaustive-match.rs
@@ -32,14 +32,14 @@ fn main() {
     let vec = vec![Some(42), None, Some(21)];
     let vec: &[Option<isize>] = &vec;
     match *vec { //~ ERROR non-exhaustive patterns: `[]` not covered
-        [Some(..), None, ref tail..] => {}
-        [Some(..), Some(..), ref tail..] => {}
+        [Some(..), None, ref tail @ ..] => {}
+        [Some(..), Some(..), ref tail @ ..] => {}
         [None] => {}
     }
     let vec = vec![1];
     let vec: &[isize] = &vec;
     match *vec {
-        [_, ref tail..] => (),
+        [_, ref tail @ ..] => (),
         [] => ()
     }
     let vec = vec![0.5f32];
@@ -53,10 +53,10 @@ fn main() {
     let vec = vec![Some(42), None, Some(21)];
     let vec: &[Option<isize>] = &vec;
     match *vec {
-        [Some(..), None, ref tail..] => {}
-        [Some(..), Some(..), ref tail..] => {}
-        [None, None, ref tail..] => {}
-        [None, Some(..), ref tail..] => {}
+        [Some(..), None, ref tail @ ..] => {}
+        [Some(..), Some(..), ref tail @ ..] => {}
+        [None, None, ref tail @ ..] => {}
+        [None, Some(..), ref tail @ ..] => {}
         [Some(_)] => {}
         [None] => {}
         [] => {}
diff --git a/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs b/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs
index 9fcd4bdad72..4ca1cbcebcc 100644
--- a/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs
+++ b/src/test/ui/non-exhaustive/non-exhaustive-pattern-witness.rs
@@ -77,7 +77,7 @@ fn vectors_with_nested_enums() {
         [Enum::Second(true), Enum::First] => (),
         [Enum::Second(true), Enum::Second(true)] => (),
         [Enum::Second(false), _] => (),
-        [_, _, ref tail.., _] => ()
+        [_, _, ref tail @ .., _] => ()
     }
 }
 
diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/parser/match-vec-invalid.rs
index e5e85ba8ca6..00f4374b256 100644
--- a/src/test/ui/parser/match-vec-invalid.rs
+++ b/src/test/ui/parser/match-vec-invalid.rs
@@ -1,7 +1,13 @@
 fn main() {
-    let a = Vec::new();
+    let a: &[u8] = &[];
     match a {
-        [1, tail.., tail..] => {}, //~ ERROR: expected one of `,` or `@`, found `..`
+        [1, tail @ .., tail @ ..] => {},
+        //~^ ERROR identifier `tail` is bound more than once in the same pattern
+        //~| ERROR subslice patterns are unstable
+        //~| ERROR subslice patterns are unstable
+        //~| ERROR `..` can only be used once per slice pattern
         _ => ()
     }
 }
+
+const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/parser/match-vec-invalid.stderr
index fee8d248dcf..0956ac21b7f 100644
--- a/src/test/ui/parser/match-vec-invalid.stderr
+++ b/src/test/ui/parser/match-vec-invalid.stderr
@@ -1,8 +1,45 @@
-error: expected one of `,` or `@`, found `..`
-  --> $DIR/match-vec-invalid.rs:4:25
+error[E0416]: identifier `tail` is bound more than once in the same pattern
+  --> $DIR/match-vec-invalid.rs:4:24
    |
-LL |         [1, tail.., tail..] => {},
-   |                         ^^ expected one of `,` or `@` here
+LL |         [1, tail @ .., tail @ ..] => {},
+   |                        ^^^^ used in a pattern more than once
 
-error: aborting due to previous error
+error[E0658]: subslice patterns are unstable
+  --> $DIR/match-vec-invalid.rs:4:13
+   |
+LL |         [1, tail @ .., tail @ ..] => {},
+   |             ^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62254
+   = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
+
+error[E0658]: subslice patterns are unstable
+  --> $DIR/match-vec-invalid.rs:4:24
+   |
+LL |         [1, tail @ .., tail @ ..] => {},
+   |                        ^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62254
+   = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
+
+error: `..` can only be used once per slice pattern
+  --> $DIR/match-vec-invalid.rs:4:31
+   |
+LL |         [1, tail @ .., tail @ ..] => {},
+   |                    --         ^^ can only be used once per slice pattern
+   |                    |
+   |                    previously used here
+
+error[E0308]: mismatched types
+  --> $DIR/match-vec-invalid.rs:13:30
+   |
+LL | const RECOVERY_WITNESS: () = 0;
+   |                              ^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error: aborting due to 5 previous errors
 
+Some errors have detailed explanations: E0308, E0416, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs
index 9bad0cb25c1..7b972183099 100644
--- a/src/test/ui/parser/pat-lt-bracket-6.rs
+++ b/src/test/ui/parser/pat-lt-bracket-6.rs
@@ -1,3 +1,9 @@
 fn main() {
+    struct Test(&'static u8, [u8; 0]);
+    let x = Test(&0, []);
+
     let Test(&desc[..]) = x; //~ ERROR: expected one of `)`, `,`, or `@`, found `[`
+    //~^ ERROR subslice patterns are unstable
 }
+
+const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr
index 2ee4bdb20fe..201465b2c85 100644
--- a/src/test/ui/parser/pat-lt-bracket-6.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-6.stderr
@@ -1,8 +1,28 @@
 error: expected one of `)`, `,`, or `@`, found `[`
-  --> $DIR/pat-lt-bracket-6.rs:2:19
+  --> $DIR/pat-lt-bracket-6.rs:5:19
    |
 LL |     let Test(&desc[..]) = x;
    |                   ^ expected one of `)`, `,`, or `@` here
 
-error: aborting due to previous error
+error[E0658]: subslice patterns are unstable
+  --> $DIR/pat-lt-bracket-6.rs:5:20
+   |
+LL |     let Test(&desc[..]) = x;
+   |                    ^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/62254
+   = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
+
+error[E0308]: mismatched types
+  --> $DIR/pat-lt-bracket-6.rs:9:30
+   |
+LL | const RECOVERY_WITNESS: () = 0;
+   |                              ^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0308, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/pat-lt-bracket-7.rs b/src/test/ui/parser/pat-lt-bracket-7.rs
index 36c0d773373..020fdb845e8 100644
--- a/src/test/ui/parser/pat-lt-bracket-7.rs
+++ b/src/test/ui/parser/pat-lt-bracket-7.rs
@@ -1,3 +1,8 @@
 fn main() {
-    for thing(x[]) in foo {} //~ ERROR: expected one of `)`, `,`, or `@`, found `[`
+    struct Thing(u8, [u8; 0]);
+    let foo = core::iter::empty();
+
+    for Thing(x[]) in foo {} //~ ERROR: expected one of `)`, `,`, or `@`, found `[`
 }
+
+const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr
index 5552ea46d9b..17557efa49e 100644
--- a/src/test/ui/parser/pat-lt-bracket-7.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-7.stderr
@@ -1,8 +1,18 @@
 error: expected one of `)`, `,`, or `@`, found `[`
-  --> $DIR/pat-lt-bracket-7.rs:2:16
+  --> $DIR/pat-lt-bracket-7.rs:5:16
    |
-LL |     for thing(x[]) in foo {}
+LL |     for Thing(x[]) in foo {}
    |                ^ expected one of `)`, `,`, or `@` here
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/pat-lt-bracket-7.rs:8:30
+   |
+LL | const RECOVERY_WITNESS: () = 0;
+   |                              ^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/pat-tuple-2.rs b/src/test/ui/parser/pat-tuple-2.rs
index fd25499381a..a8f3debd3d6 100644
--- a/src/test/ui/parser/pat-tuple-2.rs
+++ b/src/test/ui/parser/pat-tuple-2.rs
@@ -1,6 +1,7 @@
+// check-pass
+
 fn main() {
     match (0, 1, 2) {
         (pat, ..,) => {}
-        //~^ ERROR trailing comma is not permitted after `..`
     }
 }
diff --git a/src/test/ui/parser/pat-tuple-2.stderr b/src/test/ui/parser/pat-tuple-2.stderr
deleted file mode 100644
index c3a5c39a8e3..00000000000
--- a/src/test/ui/parser/pat-tuple-2.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: trailing comma is not permitted after `..`
-  --> $DIR/pat-tuple-2.rs:3:17
-   |
-LL |         (pat, ..,) => {}
-   |                 ^ trailing comma is not permitted after `..`
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/pat-tuple-3.rs b/src/test/ui/parser/pat-tuple-3.rs
index e1e975d3c3e..1486ab231aa 100644
--- a/src/test/ui/parser/pat-tuple-3.rs
+++ b/src/test/ui/parser/pat-tuple-3.rs
@@ -1,6 +1,6 @@
 fn main() {
     match (0, 1, 2) {
         (.., pat, ..) => {}
-        //~^ ERROR `..` can only be used once per tuple or tuple struct pattern
+        //~^ ERROR `..` can only be used once per tuple pattern
     }
 }
diff --git a/src/test/ui/parser/pat-tuple-3.stderr b/src/test/ui/parser/pat-tuple-3.stderr
index c9f14bb9042..9ac0611c5c9 100644
--- a/src/test/ui/parser/pat-tuple-3.stderr
+++ b/src/test/ui/parser/pat-tuple-3.stderr
@@ -1,10 +1,10 @@
-error: `..` can only be used once per tuple or tuple struct pattern
+error: `..` can only be used once per tuple pattern
   --> $DIR/pat-tuple-3.rs:3:19
    |
 LL |         (.., pat, ..) => {}
-   |          --       ^^ can only be used once per pattern
+   |          --       ^^ can only be used once per tuple pattern
    |          |
-   |          previously present here
+   |          previously used here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-tuple-4.rs b/src/test/ui/parser/pat-tuple-4.rs
index 76f60d94bc8..2f03160430a 100644
--- a/src/test/ui/parser/pat-tuple-4.rs
+++ b/src/test/ui/parser/pat-tuple-4.rs
@@ -1,5 +1,11 @@
 fn main() {
+    const PAT: u8 = 0;
+
     match 0 {
-        (.. pat) => {} //~ ERROR expected one of `)` or `,`, found `pat`
+        (.. PAT) => {}
+        //~^ ERROR `..X` range patterns are not supported
+        //~| ERROR exclusive range pattern syntax is experimental
     }
 }
+
+const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/parser/pat-tuple-4.stderr b/src/test/ui/parser/pat-tuple-4.stderr
index 26b92fae313..af3ecce1846 100644
--- a/src/test/ui/parser/pat-tuple-4.stderr
+++ b/src/test/ui/parser/pat-tuple-4.stderr
@@ -1,8 +1,28 @@
-error: expected one of `)` or `,`, found `pat`
-  --> $DIR/pat-tuple-4.rs:3:13
+error: `..X` range patterns are not supported
+  --> $DIR/pat-tuple-4.rs:5:10
    |
-LL |         (.. pat) => {}
-   |             ^^^ expected one of `)` or `,` here
+LL |         (.. PAT) => {}
+   |          ^^^^^^ help: try using the minimum value for the type: `MIN..PAT`
 
-error: aborting due to previous error
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/pat-tuple-4.rs:5:10
+   |
+LL |         (.. PAT) => {}
+   |          ^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/37854
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error[E0308]: mismatched types
+  --> $DIR/pat-tuple-4.rs:11:30
+   |
+LL | const RECOVERY_WITNESS: () = 0;
+   |                              ^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0308, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/pat-tuple-5.rs b/src/test/ui/parser/pat-tuple-5.rs
index d4f05a5eb52..5334ef93bb3 100644
--- a/src/test/ui/parser/pat-tuple-5.rs
+++ b/src/test/ui/parser/pat-tuple-5.rs
@@ -1,5 +1,10 @@
 fn main() {
+    const PAT: u8 = 0;
+
     match (0, 1) {
-        (pat ..) => {} //~ ERROR unexpected token: `)`
+        (PAT ..) => {}
+        //~^ ERROR `X..` range patterns are not supported
+        //~| ERROR exclusive range pattern syntax is experimental
+        //~| ERROR mismatched types
     }
 }
diff --git a/src/test/ui/parser/pat-tuple-5.stderr b/src/test/ui/parser/pat-tuple-5.stderr
index f9832214c68..09ebdc29a21 100644
--- a/src/test/ui/parser/pat-tuple-5.stderr
+++ b/src/test/ui/parser/pat-tuple-5.stderr
@@ -1,8 +1,30 @@
-error: unexpected token: `)`
-  --> $DIR/pat-tuple-5.rs:3:16
+error: `X..` range patterns are not supported
+  --> $DIR/pat-tuple-5.rs:5:10
    |
-LL |         (pat ..) => {}
-   |                ^
+LL |         (PAT ..) => {}
+   |          ^^^^^^ help: try using the maximum value for the type: `PAT..MAX`
 
-error: aborting due to previous error
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/pat-tuple-5.rs:5:10
+   |
+LL |         (PAT ..) => {}
+   |          ^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/37854
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+
+error[E0308]: mismatched types
+  --> $DIR/pat-tuple-5.rs:5:10
+   |
+LL |     match (0, 1) {
+   |           ------ this match expression has type `({integer}, {integer})`
+LL |         (PAT ..) => {}
+   |          ^^^^^^ expected tuple, found u8
+   |
+   = note: expected type `({integer}, {integer})`
+              found type `u8`
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0308, E0658.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/recover-range-pats.rs b/src/test/ui/parser/recover-range-pats.rs
new file mode 100644
index 00000000000..c66652ff4fa
--- /dev/null
+++ b/src/test/ui/parser/recover-range-pats.rs
@@ -0,0 +1,123 @@
+// Here we test all kinds of range patterns in terms of parsing / recovery.
+// We want to ensure that:
+// 1. Things parse as they should.
+// 2. Or at least we have parser recovery if they don't.
+
+#![feature(exclusive_range_pattern)]
+#![deny(ellipsis_inclusive_range_patterns)]
+
+fn main() {}
+
+const X: u8 = 0;
+const Y: u8 = 3;
+
+fn exclusive_from_to() {
+    if let 0..3 = 0 {} // OK.
+    if let 0..Y = 0 {} // OK.
+    if let X..3 = 0 {} // OK.
+    if let X..Y = 0 {} // OK.
+    if let true..Y = 0 {} //~ ERROR only char and numeric types
+    if let X..true = 0 {} //~ ERROR only char and numeric types
+    if let .0..Y = 0 {} //~ ERROR mismatched types
+    //~^ ERROR float literals must have an integer part
+    if let X.. .0 = 0 {} //~ ERROR mismatched types
+    //~^ ERROR float literals must have an integer part
+}
+
+fn inclusive_from_to() {
+    if let 0..=3 = 0 {} // OK.
+    if let 0..=Y = 0 {} // OK.
+    if let X..=3 = 0 {} // OK.
+    if let X..=Y = 0 {} // OK.
+    if let true..=Y = 0 {} //~ ERROR only char and numeric types
+    if let X..=true = 0 {} //~ ERROR only char and numeric types
+    if let .0..=Y = 0 {} //~ ERROR mismatched types
+    //~^ ERROR float literals must have an integer part
+    if let X..=.0 = 0 {} //~ ERROR mismatched types
+    //~^ ERROR float literals must have an integer part
+}
+
+fn inclusive2_from_to() {
+    if let 0...3 = 0 {} //~ ERROR `...` range patterns are deprecated
+    if let 0...Y = 0 {} //~ ERROR `...` range patterns are deprecated
+    if let X...3 = 0 {} //~ ERROR `...` range patterns are deprecated
+    if let X...Y = 0 {} //~ ERROR `...` range patterns are deprecated
+    if let true...Y = 0 {} //~ ERROR only char and numeric types
+    //~^ ERROR `...` range patterns are deprecated
+    if let X...true = 0 {} //~ ERROR only char and numeric types
+    //~^ ERROR `...` range patterns are deprecated
+    if let .0...Y = 0 {} //~ ERROR mismatched types
+    //~^ ERROR float literals must have an integer part
+    //~| ERROR `...` range patterns are deprecated
+    if let X... .0 = 0 {} //~ ERROR mismatched types
+    //~^ ERROR float literals must have an integer part
+    //~| ERROR `...` range patterns are deprecated
+}
+
+fn exclusive_from() {
+    if let 0.. = 0 {} //~ ERROR `X..` range patterns are not supported
+    if let X.. = 0 {} //~ ERROR `X..` range patterns are not supported
+    if let true.. = 0 {} //~ ERROR `X..` range patterns are not supported
+    //~^ ERROR only char and numeric types
+    if let .0.. = 0 {} //~ ERROR `X..` range patterns are not supported
+    //~^ ERROR float literals must have an integer part
+    //~| ERROR mismatched types
+}
+
+fn inclusive_from() {
+    if let 0..= = 0 {} //~ ERROR `X..=` range patterns are not supported
+    if let X..= = 0 {} //~ ERROR `X..=` range patterns are not supported
+    if let true..= = 0 {} //~ ERROR `X..=` range patterns are not supported
+    //~| ERROR only char and numeric types
+    if let .0..= = 0 {} //~ ERROR `X..=` range patterns are not supported
+    //~^ ERROR float literals must have an integer part
+    //~| ERROR mismatched types
+}
+
+fn inclusive2_from() {
+    if let 0... = 0 {} //~ ERROR `X...` range patterns are not supported
+    //~^ ERROR `...` range patterns are deprecated
+    if let X... = 0 {} //~ ERROR `X...` range patterns are not supported
+    //~^ ERROR `...` range patterns are deprecated
+    if let true... = 0 {} //~ ERROR `X...` range patterns are not supported
+    //~^ ERROR `...` range patterns are deprecated
+    //~| ERROR only char and numeric types
+    if let .0... = 0 {} //~ ERROR `X...` range patterns are not supported
+    //~^ ERROR float literals must have an integer part
+    //~| ERROR `...` range patterns are deprecated
+    //~| ERROR mismatched types
+}
+
+fn exclusive_to() {
+    if let ..0 = 0 {} //~ ERROR `..X` range patterns are not supported
+    if let ..Y = 0 {} //~ ERROR `..X` range patterns are not supported
+    if let ..true = 0 {} //~ ERROR `..X` range patterns are not supported
+    //~| ERROR only char and numeric types
+    if let .. .0 = 0 {} //~ ERROR `..X` range patterns are not supported
+    //~^ ERROR float literals must have an integer part
+    //~| ERROR mismatched types
+}
+
+fn inclusive_to() {
+    if let ..=3 = 0 {} //~ ERROR `..=X` range patterns are not supported
+    if let ..=Y = 0 {} //~ ERROR `..=X` range patterns are not supported
+    if let ..=true = 0 {} //~ ERROR `..=X` range patterns are not supported
+    //~| ERROR only char and numeric types
+    if let ..=.0 = 0 {} //~ ERROR `..=X` range patterns are not supported
+    //~^ ERROR float literals must have an integer part
+    //~| ERROR mismatched types
+}
+
+fn inclusive2_to() {
+    if let ...3 = 0 {} //~ ERROR `...X` range patterns are not supported
+    //~^ ERROR `...` range patterns are deprecated
+    if let ...Y = 0 {} //~ ERROR `...X` range patterns are not supported
+    //~^ ERROR `...` range patterns are deprecated
+    if let ...true = 0 {} //~ ERROR `...X` range patterns are not supported
+    //~^ ERROR `...` range patterns are deprecated
+    //~| ERROR only char and numeric types
+    if let ....3 = 0 {} //~ ERROR `...X` range patterns are not supported
+    //~^ ERROR float literals must have an integer part
+    //~| ERROR `...` range patterns are deprecated
+    //~| ERROR mismatched types
+}
diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr
new file mode 100644
index 00000000000..c50d5e6eb61
--- /dev/null
+++ b/src/test/ui/parser/recover-range-pats.stderr
@@ -0,0 +1,538 @@
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:21:12
+   |
+LL |     if let .0..Y = 0 {}
+   |            ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:23:16
+   |
+LL |     if let X.. .0 = 0 {}
+   |                ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:34:12
+   |
+LL |     if let .0..=Y = 0 {}
+   |            ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:36:16
+   |
+LL |     if let X..=.0 = 0 {}
+   |                ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:49:12
+   |
+LL |     if let .0...Y = 0 {}
+   |            ^^ help: must have an integer part: `0.0`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:52:17
+   |
+LL |     if let X... .0 = 0 {}
+   |                 ^^ help: must have an integer part: `0.0`
+
+error: `X..` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:58:12
+   |
+LL |     if let 0.. = 0 {}
+   |            ^^^ help: try using the maximum value for the type: `0..MAX`
+
+error: `X..` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:59:12
+   |
+LL |     if let X.. = 0 {}
+   |            ^^^ help: try using the maximum value for the type: `X..MAX`
+
+error: `X..` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:60:12
+   |
+LL |     if let true.. = 0 {}
+   |            ^^^^^^ help: try using the maximum value for the type: `true..MAX`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:62:12
+   |
+LL |     if let .0.. = 0 {}
+   |            ^^ help: must have an integer part: `0.0`
+
+error: `X..` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:62:12
+   |
+LL |     if let .0.. = 0 {}
+   |            ^^^^ help: try using the maximum value for the type: `0.0..MAX`
+
+error: `X..=` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:68:12
+   |
+LL |     if let 0..= = 0 {}
+   |            ^^^^ help: try using the maximum value for the type: `0..=MAX`
+
+error: `X..=` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:69:12
+   |
+LL |     if let X..= = 0 {}
+   |            ^^^^ help: try using the maximum value for the type: `X..=MAX`
+
+error: `X..=` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:70:12
+   |
+LL |     if let true..= = 0 {}
+   |            ^^^^^^^ help: try using the maximum value for the type: `true..=MAX`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:72:12
+   |
+LL |     if let .0..= = 0 {}
+   |            ^^ help: must have an integer part: `0.0`
+
+error: `X..=` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:72:12
+   |
+LL |     if let .0..= = 0 {}
+   |            ^^^^^ help: try using the maximum value for the type: `0.0..=MAX`
+
+error: `X...` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:78:12
+   |
+LL |     if let 0... = 0 {}
+   |            ^^^^ help: try using the maximum value for the type: `0...MAX`
+
+error: `X...` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:80:12
+   |
+LL |     if let X... = 0 {}
+   |            ^^^^ help: try using the maximum value for the type: `X...MAX`
+
+error: `X...` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:82:12
+   |
+LL |     if let true... = 0 {}
+   |            ^^^^^^^ help: try using the maximum value for the type: `true...MAX`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:85:12
+   |
+LL |     if let .0... = 0 {}
+   |            ^^ help: must have an integer part: `0.0`
+
+error: `X...` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:85:12
+   |
+LL |     if let .0... = 0 {}
+   |            ^^^^^ help: try using the maximum value for the type: `0.0...MAX`
+
+error: `..X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:92:12
+   |
+LL |     if let ..0 = 0 {}
+   |            ^^^ help: try using the minimum value for the type: `MIN..0`
+
+error: `..X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:93:12
+   |
+LL |     if let ..Y = 0 {}
+   |            ^^^ help: try using the minimum value for the type: `MIN..Y`
+
+error: `..X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:94:12
+   |
+LL |     if let ..true = 0 {}
+   |            ^^^^^^ help: try using the minimum value for the type: `MIN..true`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:96:15
+   |
+LL |     if let .. .0 = 0 {}
+   |               ^^ help: must have an integer part: `0.0`
+
+error: `..X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:96:12
+   |
+LL |     if let .. .0 = 0 {}
+   |            ^^^^^ help: try using the minimum value for the type: `MIN..0.0`
+
+error: `..=X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:102:12
+   |
+LL |     if let ..=3 = 0 {}
+   |            ^^^^ help: try using the minimum value for the type: `MIN..=3`
+
+error: `..=X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:103:12
+   |
+LL |     if let ..=Y = 0 {}
+   |            ^^^^ help: try using the minimum value for the type: `MIN..=Y`
+
+error: `..=X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:104:12
+   |
+LL |     if let ..=true = 0 {}
+   |            ^^^^^^^ help: try using the minimum value for the type: `MIN..=true`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:106:15
+   |
+LL |     if let ..=.0 = 0 {}
+   |               ^^ help: must have an integer part: `0.0`
+
+error: `..=X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:106:12
+   |
+LL |     if let ..=.0 = 0 {}
+   |            ^^^^^ help: try using the minimum value for the type: `MIN..=0.0`
+
+error: `...X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:112:12
+   |
+LL |     if let ...3 = 0 {}
+   |            ^^^^ help: try using the minimum value for the type: `MIN...3`
+
+error: `...X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:114:12
+   |
+LL |     if let ...Y = 0 {}
+   |            ^^^^ help: try using the minimum value for the type: `MIN...Y`
+
+error: `...X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:116:12
+   |
+LL |     if let ...true = 0 {}
+   |            ^^^^^^^ help: try using the minimum value for the type: `MIN...true`
+
+error: float literals must have an integer part
+  --> $DIR/recover-range-pats.rs:119:15
+   |
+LL |     if let ....3 = 0 {}
+   |               ^^ help: must have an integer part: `0.3`
+
+error: `...X` range patterns are not supported
+  --> $DIR/recover-range-pats.rs:119:12
+   |
+LL |     if let ....3 = 0 {}
+   |            ^^^^^ help: try using the minimum value for the type: `MIN...0.3`
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:41:13
+   |
+LL |     if let 0...3 = 0 {}
+   |             ^^^ help: use `..=` for an inclusive range
+   |
+note: lint level defined here
+  --> $DIR/recover-range-pats.rs:7:9
+   |
+LL | #![deny(ellipsis_inclusive_range_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:42:13
+   |
+LL |     if let 0...Y = 0 {}
+   |             ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:43:13
+   |
+LL |     if let X...3 = 0 {}
+   |             ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:44:13
+   |
+LL |     if let X...Y = 0 {}
+   |             ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:45:16
+   |
+LL |     if let true...Y = 0 {}
+   |                ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:47:13
+   |
+LL |     if let X...true = 0 {}
+   |             ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:49:14
+   |
+LL |     if let .0...Y = 0 {}
+   |              ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:52:13
+   |
+LL |     if let X... .0 = 0 {}
+   |             ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:78:13
+   |
+LL |     if let 0... = 0 {}
+   |             ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:80:13
+   |
+LL |     if let X... = 0 {}
+   |             ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:82:16
+   |
+LL |     if let true... = 0 {}
+   |                ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:85:14
+   |
+LL |     if let .0... = 0 {}
+   |              ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:112:12
+   |
+LL |     if let ...3 = 0 {}
+   |            ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:114:12
+   |
+LL |     if let ...Y = 0 {}
+   |            ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:116:12
+   |
+LL |     if let ...true = 0 {}
+   |            ^^^ help: use `..=` for an inclusive range
+
+error: `...` range patterns are deprecated
+  --> $DIR/recover-range-pats.rs:119:12
+   |
+LL |     if let ....3 = 0 {}
+   |            ^^^ help: use `..=` for an inclusive range
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:19:12
+   |
+LL |     if let true..Y = 0 {}
+   |            ^^^^ ranges require char or numeric types
+   |
+   = note: start type: bool
+   = note: end type: u8
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:20:15
+   |
+LL |     if let X..true = 0 {}
+   |               ^^^^ ranges require char or numeric types
+   |
+   = note: start type: u8
+   = note: end type: bool
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:21:12
+   |
+LL |     if let .0..Y = 0 {}
+   |            ^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `{integer}`
+              found type `{float}`
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:23:12
+   |
+LL |     if let X.. .0 = 0 {}
+   |            ^^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `u8`
+              found type `{float}`
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:32:12
+   |
+LL |     if let true..=Y = 0 {}
+   |            ^^^^ ranges require char or numeric types
+   |
+   = note: start type: bool
+   = note: end type: u8
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:33:16
+   |
+LL |     if let X..=true = 0 {}
+   |                ^^^^ ranges require char or numeric types
+   |
+   = note: start type: u8
+   = note: end type: bool
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:34:12
+   |
+LL |     if let .0..=Y = 0 {}
+   |            ^^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `{integer}`
+              found type `{float}`
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:36:12
+   |
+LL |     if let X..=.0 = 0 {}
+   |            ^^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `u8`
+              found type `{float}`
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:45:12
+   |
+LL |     if let true...Y = 0 {}
+   |            ^^^^ ranges require char or numeric types
+   |
+   = note: start type: bool
+   = note: end type: u8
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:47:16
+   |
+LL |     if let X...true = 0 {}
+   |                ^^^^ ranges require char or numeric types
+   |
+   = note: start type: u8
+   = note: end type: bool
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:49:12
+   |
+LL |     if let .0...Y = 0 {}
+   |            ^^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `{integer}`
+              found type `{float}`
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:52:12
+   |
+LL |     if let X... .0 = 0 {}
+   |            ^^^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `u8`
+              found type `{float}`
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:60:12
+   |
+LL |     if let true.. = 0 {}
+   |            ^^^^ ranges require char or numeric types
+   |
+   = note: start type: bool
+   = note: end type: [type error]
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:62:12
+   |
+LL |     if let .0.. = 0 {}
+   |            ^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `{integer}`
+              found type `{float}`
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:70:12
+   |
+LL |     if let true..= = 0 {}
+   |            ^^^^ ranges require char or numeric types
+   |
+   = note: start type: bool
+   = note: end type: [type error]
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:72:12
+   |
+LL |     if let .0..= = 0 {}
+   |            ^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `{integer}`
+              found type `{float}`
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:82:12
+   |
+LL |     if let true... = 0 {}
+   |            ^^^^ ranges require char or numeric types
+   |
+   = note: start type: bool
+   = note: end type: [type error]
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:85:12
+   |
+LL |     if let .0... = 0 {}
+   |            ^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `{integer}`
+              found type `{float}`
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:94:14
+   |
+LL |     if let ..true = 0 {}
+   |              ^^^^ ranges require char or numeric types
+   |
+   = note: start type: [type error]
+   = note: end type: bool
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:96:12
+   |
+LL |     if let .. .0 = 0 {}
+   |            ^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `{integer}`
+              found type `{float}`
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:104:15
+   |
+LL |     if let ..=true = 0 {}
+   |               ^^^^ ranges require char or numeric types
+   |
+   = note: start type: [type error]
+   = note: end type: bool
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:106:12
+   |
+LL |     if let ..=.0 = 0 {}
+   |            ^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `{integer}`
+              found type `{float}`
+
+error[E0029]: only char and numeric types are allowed in range patterns
+  --> $DIR/recover-range-pats.rs:116:15
+   |
+LL |     if let ...true = 0 {}
+   |               ^^^^ ranges require char or numeric types
+   |
+   = note: start type: [type error]
+   = note: end type: bool
+
+error[E0308]: mismatched types
+  --> $DIR/recover-range-pats.rs:119:12
+   |
+LL |     if let ....3 = 0 {}
+   |            ^^^^^ expected integer, found floating-point number
+   |
+   = note: expected type `{integer}`
+              found type `{float}`
+
+error: aborting due to 76 previous errors
+
+Some errors have detailed explanations: E0029, E0308.
+For more information about an error, try `rustc --explain E0029`.
diff --git a/src/test/ui/parser/recover-tuple-pat.rs b/src/test/ui/parser/recover-tuple-pat.rs
index 488e8db6b87..7fded752d67 100644
--- a/src/test/ui/parser/recover-tuple-pat.rs
+++ b/src/test/ui/parser/recover-tuple-pat.rs
@@ -1,12 +1,12 @@
+// NOTE: This doesn't recover anymore.
+
 fn main() {
     let x = (1, 2, 3, 4);
     match x {
         (1, .., 4) => {}
         (1, .=., 4) => { let _: usize = ""; }
         //~^ ERROR expected pattern, found `.`
-        //~| ERROR mismatched types
         (.=., 4) => {}
-        //~^ ERROR expected pattern, found `.`
         (1, 2, 3, 4) => {}
     }
 }
diff --git a/src/test/ui/parser/recover-tuple-pat.stderr b/src/test/ui/parser/recover-tuple-pat.stderr
index 5919aa72355..93a6a66a630 100644
--- a/src/test/ui/parser/recover-tuple-pat.stderr
+++ b/src/test/ui/parser/recover-tuple-pat.stderr
@@ -1,24 +1,8 @@
 error: expected pattern, found `.`
-  --> $DIR/recover-tuple-pat.rs:5:13
+  --> $DIR/recover-tuple-pat.rs:7:13
    |
 LL |         (1, .=., 4) => { let _: usize = ""; }
    |             ^ expected pattern
 
-error: expected pattern, found `.`
-  --> $DIR/recover-tuple-pat.rs:8:10
-   |
-LL |         (.=., 4) => {}
-   |          ^ expected pattern
-
-error[E0308]: mismatched types
-  --> $DIR/recover-tuple-pat.rs:5:41
-   |
-LL |         (1, .=., 4) => { let _: usize = ""; }
-   |                                         ^^ expected usize, found reference
-   |
-   = note: expected type `usize`
-              found type `&'static str`
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs
index fd85bf7f160..1484b8c4a1f 100644
--- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs
+++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs
@@ -4,6 +4,6 @@ pub fn main() {
     let sl: &[u8] = b"foo";
 
     match sl { //~ ERROR non-exhaustive patterns
-        [first, remainder..] => {},
+        [first, remainder @ ..] => {},
     };
 }
diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
index 939a3c4a1fd..38b0941aad0 100644
--- a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
+++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs
@@ -5,7 +5,7 @@ fn slice_pat() {
     let sl: &[u8] = b"foo";
 
     match sl {
-        [first, remainder..] => {
+        [first, remainder @ ..] => {
             let _: &u8 = first;
             assert_eq!(first, &b'f');
             assert_eq!(remainder, b"oo");
diff --git a/src/test/ui/trailing-comma.rs b/src/test/ui/trailing-comma.rs
index f34e6b7606d..929c35a9e11 100644
--- a/src/test/ui/trailing-comma.rs
+++ b/src/test/ui/trailing-comma.rs
@@ -25,7 +25,7 @@ pub fn main() {
     let (_, _,) = (1, 1,);
     let [_, _,] = [1, 1,];
     let [_, _, .., _,] = [1, 1, 1, 1,];
-    let [_, _, _.., _,] = [1, 1, 1, 1,];
+    let [_, _, _, ..,] = [1, 1, 1, 1,];
 
     let x: Foo<isize,> = Foo::<isize,>(1);