about summary refs log tree commit diff
path: root/src/test/ui/or-patterns
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/or-patterns')
-rw-r--r--src/test/ui/or-patterns/already-bound-name.stderr8
-rw-r--r--src/test/ui/or-patterns/box-patterns.rs37
-rw-r--r--src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr3
-rw-r--r--src/test/ui/or-patterns/feature-gate-const-fn.rs2
-rw-r--r--src/test/ui/or-patterns/feature-gate-const-fn.stderr17
-rw-r--r--src/test/ui/or-patterns/inconsistent-modes.rs16
-rw-r--r--src/test/ui/or-patterns/inconsistent-modes.stderr40
-rw-r--r--src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs9
-rw-r--r--src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr27
-rw-r--r--src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs9
-rw-r--r--src/test/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs22
-rw-r--r--src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr158
-rw-r--r--src/test/ui/or-patterns/slice-patterns.rs53
13 files changed, 313 insertions, 88 deletions
diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr
index 9924b0d7f72..97933ca1229 100644
--- a/src/test/ui/or-patterns/already-bound-name.stderr
+++ b/src/test/ui/or-patterns/already-bound-name.stderr
@@ -86,12 +86,14 @@ error[E0308]: mismatched types
   --> $DIR/already-bound-name.rs:32:31
    |
 LL |     let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
-   |                               ^                    ------- this expression has type `E<E<{integer}>>`
-   |                               |
-   |                               expected integer, found enum `E`
+   |             -                 ^                    ------- this expression has type `E<E<{integer}>>`
+   |             |                 |
+   |             |                 expected integer, found enum `E`
+   |             first introduced with type `{integer}` here
    |
    = note: expected type `{integer}`
               found type `E<{integer}>`
+   = note: a binding must have the same type in all alternatives
 
 error: aborting due to 15 previous errors
 
diff --git a/src/test/ui/or-patterns/box-patterns.rs b/src/test/ui/or-patterns/box-patterns.rs
new file mode 100644
index 00000000000..aafd4799383
--- /dev/null
+++ b/src/test/ui/or-patterns/box-patterns.rs
@@ -0,0 +1,37 @@
+// Test or-patterns with box-patterns
+
+// run-pass
+
+#![feature(or_patterns)]
+#![feature(box_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum MatchArm {
+    Arm(usize),
+    Wild,
+}
+
+#[derive(Debug)]
+enum Test {
+    Foo,
+    Bar,
+    Baz,
+    Qux,
+}
+
+fn test(x: Option<Box<Test>>) -> MatchArm {
+    match x {
+        Some(box Test::Foo | box Test::Bar) => MatchArm::Arm(0),
+        Some(box Test::Baz) => MatchArm::Arm(1),
+        Some(_) => MatchArm::Arm(2),
+        _ => MatchArm::Wild,
+    }
+}
+
+fn main() {
+    assert_eq!(test(Some(Box::new(Test::Foo))), MatchArm::Arm(0));
+    assert_eq!(test(Some(Box::new(Test::Bar))), MatchArm::Arm(0));
+    assert_eq!(test(Some(Box::new(Test::Baz))), MatchArm::Arm(1));
+    assert_eq!(test(Some(Box::new(Test::Qux))), MatchArm::Arm(2));
+    assert_eq!(test(None), MatchArm::Wild);
+}
diff --git a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr
index 3ba26de10d3..b45e947f3ea 100644
--- a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr
+++ b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.stderr
@@ -5,6 +5,7 @@ LL |     match (0u8, 0u8) {
    |           ^^^^^^^^^^ pattern `(2u8..=std::u8::MAX, _)` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `(u8, u8)`
 
 error[E0004]: non-exhaustive patterns: `((4u8..=std::u8::MAX))` not covered
   --> $DIR/exhaustiveness-non-exhaustive.rs:10:11
@@ -13,6 +14,7 @@ LL |     match ((0u8,),) {
    |           ^^^^^^^^^ pattern `((4u8..=std::u8::MAX))` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `((u8,),)`
 
 error[E0004]: non-exhaustive patterns: `(Some(2u8..=std::u8::MAX))` not covered
   --> $DIR/exhaustiveness-non-exhaustive.rs:14:11
@@ -21,6 +23,7 @@ LL |     match (Some(0u8),) {
    |           ^^^^^^^^^^^^ pattern `(Some(2u8..=std::u8::MAX))` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `(std::option::Option<u8>,)`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/or-patterns/feature-gate-const-fn.rs b/src/test/ui/or-patterns/feature-gate-const-fn.rs
index 2ef5537db60..d21cf3dc72c 100644
--- a/src/test/ui/or-patterns/feature-gate-const-fn.rs
+++ b/src/test/ui/or-patterns/feature-gate-const-fn.rs
@@ -30,8 +30,6 @@ fn main() {
         let x = Ok(3);
         let Ok(y) | Err(y) = x;
         //~^ ERROR or-pattern is not allowed in a `const`
-        //~| ERROR constant contains unimplemented expression type
-        //~| ERROR constant contains unimplemented expression type
         2
     }];
 }
diff --git a/src/test/ui/or-patterns/feature-gate-const-fn.stderr b/src/test/ui/or-patterns/feature-gate-const-fn.stderr
index 38233a944cf..345d6c70981 100644
--- a/src/test/ui/or-patterns/feature-gate-const-fn.stderr
+++ b/src/test/ui/or-patterns/feature-gate-const-fn.stderr
@@ -52,19 +52,6 @@ LL |         let Ok(y) | Err(y) = x;
    = note: see issue #49146 <https://github.com/rust-lang/rust/issues/49146> for more information
    = help: add `#![feature(const_if_match)]` to the crate attributes to enable
 
-error[E0019]: constant contains unimplemented expression type
-  --> $DIR/feature-gate-const-fn.rs:31:25
-   |
-LL |         let Ok(y) | Err(y) = x;
-   |                         ^
-
-error[E0019]: constant contains unimplemented expression type
-  --> $DIR/feature-gate-const-fn.rs:31:16
-   |
-LL |         let Ok(y) | Err(y) = x;
-   |                ^
-
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0019, E0658.
-For more information about an error, try `rustc --explain E0019`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/or-patterns/inconsistent-modes.rs b/src/test/ui/or-patterns/inconsistent-modes.rs
index 28b5f0c02fe..fd5cb01ab42 100644
--- a/src/test/ui/or-patterns/inconsistent-modes.rs
+++ b/src/test/ui/or-patterns/inconsistent-modes.rs
@@ -5,22 +5,22 @@
 fn main() {
     // One level:
     let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
-    //~^ ERROR variable `a` is bound in inconsistent ways
+    //~^ ERROR variable `a` is bound inconsistently
     let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
-    //~^ ERROR variable `a` is bound in inconsistent ways
+    //~^ ERROR variable `a` is bound inconsistently
     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
-    //~^ ERROR variable `a` is bound in inconsistent ways
+    //~^ ERROR variable `a` is bound inconsistently
     //~| ERROR mismatched types
     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
-    //~^ ERROR variable `a` is bound in inconsistent ways
-    //~| ERROR variable `b` is bound in inconsistent ways
+    //~^ ERROR variable `a` is bound inconsistently
+    //~| ERROR variable `b` is bound inconsistently
     //~| ERROR mismatched types
 
     // Two levels:
     let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
-    //~^ ERROR variable `a` is bound in inconsistent ways
+    //~^ ERROR variable `a` is bound inconsistently
 
     // Three levels:
-    let Ok([ Ok((Ok(ref a) | Err(a),)) | Err(a) ]) | Err(a) = Err(&1);
-    //~^ ERROR variable `a` is bound in inconsistent ways
+    let Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a) = Err(&1);
+    //~^ ERROR variable `a` is bound inconsistently
 }
diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr
index c329f905960..c5dcef36e05 100644
--- a/src/test/ui/or-patterns/inconsistent-modes.stderr
+++ b/src/test/ui/or-patterns/inconsistent-modes.stderr
@@ -1,4 +1,4 @@
-error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
   --> $DIR/inconsistent-modes.rs:7:25
    |
 LL |     let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
@@ -6,7 +6,7 @@ LL |     let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
    |            |
    |            first binding
 
-error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
   --> $DIR/inconsistent-modes.rs:9:29
    |
 LL |     let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
@@ -14,25 +14,25 @@ LL |     let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
    |                    |
    |                    first binding
 
-error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
   --> $DIR/inconsistent-modes.rs:11:33
    |
 LL |     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
    |                - first binding  ^ bound in different ways
 
-error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
   --> $DIR/inconsistent-modes.rs:14:39
    |
 LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
    |                 - first binding       ^ bound in different ways
 
-error[E0409]: variable `b` is bound in inconsistent ways within the same match arm
+error[E0409]: variable `b` is bound inconsistently across alternatives separated by `|`
   --> $DIR/inconsistent-modes.rs:14:46
    |
 LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
    |                    - first binding           ^ bound in different ways
 
-error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
   --> $DIR/inconsistent-modes.rs:20:38
    |
 LL |     let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
@@ -40,35 +40,39 @@ LL |     let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
    |                        |
    |                        first binding
 
-error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
-  --> $DIR/inconsistent-modes.rs:24:34
+error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
+  --> $DIR/inconsistent-modes.rs:24:33
    |
-LL |     let Ok([ Ok((Ok(ref a) | Err(a),)) | Err(a) ]) | Err(a) = Err(&1);
-   |                         -        ^ bound in different ways
-   |                         |
-   |                         first binding
+LL |     let Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a) = Err(&1);
+   |                        -        ^ bound in different ways
+   |                        |
+   |                        first binding
 
 error[E0308]: mismatched types
   --> $DIR/inconsistent-modes.rs:11:25
    |
 LL |     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
-   |                         ^^^^^^^^^   -------------------- expected due to this
-   |                         |
-   |                         types differ in mutability
+   |            -----        ^^^^^^^^^   -------------------- expected due to this
+   |            |            |
+   |            |            types differ in mutability
+   |            first introduced with type `&&u8` here
    |
    = note: expected type `&&u8`
               found type `&mut &mut u8`
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/inconsistent-modes.rs:14:31
    |
 LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
-   |                               ^^^^^^^^^            ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>`
-   |                               |
-   |                               types differ in mutability
+   |             -----             ^^^^^^^^^            ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>`
+   |             |                 |
+   |             |                 types differ in mutability
+   |             first introduced with type `&{integer}` here
    |
    = note: expected type `&{integer}`
               found type `&mut _`
+   = note: a binding must have the same type in all alternatives
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs
new file mode 100644
index 00000000000..59533cefea6
--- /dev/null
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs
@@ -0,0 +1,9 @@
+#![feature(or_patterns)]
+
+fn main() {
+    let 0 | (1 | 2) = 0; //~ ERROR refutable pattern in local binding
+    match 0 {
+        //~^ ERROR non-exhaustive patterns
+        0 | (1 | 2) => {}
+    }
+}
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
new file mode 100644
index 00000000000..351700a6aa5
--- /dev/null
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
@@ -0,0 +1,27 @@
+error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `3i32..=std::i32::MAX` not covered
+  --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:4:9
+   |
+LL |     let 0 | (1 | 2) = 0;
+   |         ^^^^^^^^^^^ patterns `std::i32::MIN..=-1i32` and `3i32..=std::i32::MAX` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: the matched value is of type `i32`
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |     if let 0 | (1 | 2) = 0 { /* */ }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0004]: non-exhaustive patterns: `std::i32::MIN..=-1i32` and `3i32..=std::i32::MAX` not covered
+  --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:5:11
+   |
+LL |     match 0 {
+   |           ^ patterns `std::i32::MIN..=-1i32` and `3i32..=std::i32::MAX` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `i32`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0004, E0005.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs
new file mode 100644
index 00000000000..1de563dedbf
--- /dev/null
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![feature(or_patterns)]
+
+fn main() {
+    let 0 | (1 | _) = 0;
+    if let 0 | (1 | 2) = 0 {}
+    if let x @ 0 | x @ (1 | 2) = 0 {}
+}
diff --git a/src/test/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs b/src/test/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs
new file mode 100644
index 00000000000..eb6706e5000
--- /dev/null
+++ b/src/test/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+#![deny(unreachable_patterns)]
+
+#![feature(or_patterns)]
+fn main() {
+    match (3,42) {
+        (a,_) | (_,a) if a > 10 => {println!("{}", a)}
+        _ => ()
+    }
+
+    match Some((3,42)) {
+        Some((a, _)) | Some((_, a)) if a > 10 => {println!("{}", a)}
+        _ => ()
+
+    }
+
+    match Some((3,42)) {
+        Some((a, _) | (_, a)) if a > 10 => {println!("{}", a)}
+        _ => ()
+    }
+}
diff --git a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr
index 5094f04b920..1dabb7c9754 100644
--- a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr
+++ b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr
@@ -4,7 +4,11 @@ error[E0308]: mismatched types
 LL |     match Blah::A(1, 1, 2) {
    |           ---------------- this expression has type `main::Blah`
 LL |         Blah::A(_, x, y) | Blah::B(x, y) => {}
-   |                                       ^ expected `usize`, found `isize`
+   |                       -               ^ expected `usize`, found `isize`
+   |                       |
+   |                       first introduced with type `usize` here
+   |
+   = note: in the same arm, a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:17:44
@@ -12,7 +16,11 @@ error[E0308]: mismatched types
 LL |     match Some(Blah::A(1, 1, 2)) {
    |           ---------------------- this expression has type `std::option::Option<main::Blah>`
 LL |         Some(Blah::A(_, x, y) | Blah::B(x, y)) => {}
-   |                                            ^ expected `usize`, found `isize`
+   |                            -               ^ expected `usize`, found `isize`
+   |                            |
+   |                            first introduced with type `usize` here
+   |
+   = note: in the same arm, a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:21:19
@@ -20,7 +28,11 @@ error[E0308]: mismatched types
 LL |     match (0u8, 1u16) {
    |           ----------- this expression has type `(u8, u16)`
 LL |         (x, y) | (y, x) => {}
-   |                   ^ expected `u16`, found `u8`
+   |             -     ^ expected `u16`, found `u8`
+   |             |
+   |             first introduced with type `u16` here
+   |
+   = note: in the same arm, a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:21:22
@@ -28,7 +40,11 @@ error[E0308]: mismatched types
 LL |     match (0u8, 1u16) {
    |           ----------- this expression has type `(u8, u16)`
 LL |         (x, y) | (y, x) => {}
-   |                      ^ expected `u8`, found `u16`
+   |          -           ^ expected `u8`, found `u16`
+   |          |
+   |          first introduced with type `u8` here
+   |
+   = note: in the same arm, a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:26:41
@@ -36,7 +52,11 @@ error[E0308]: mismatched types
 LL |     match Some((0u8, Some((1u16, 2u32)))) {
    |           ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
 LL |         Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {}
-   |                                         ^ expected `u16`, found `u8`
+   |                        -                ^ expected `u16`, found `u8`
+   |                        |
+   |                        first introduced with type `u16` here
+   |
+   = note: in the same arm, a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:26:50
@@ -44,7 +64,11 @@ error[E0308]: mismatched types
 LL |     match Some((0u8, Some((1u16, 2u32)))) {
    |           ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
 LL |         Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {}
-   |                                                  ^ expected `u8`, found `u16`
+   |               -                                  ^ expected `u8`, found `u16`
+   |               |
+   |               first introduced with type `u8` here
+   |
+   = note: in the same arm, a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:26:59
@@ -52,7 +76,11 @@ error[E0308]: mismatched types
 LL |     match Some((0u8, Some((1u16, 2u32)))) {
    |           ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
 LL |         Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {}
-   |                                                           ^ expected `u32`, found `u16`
+   |                           -                               ^ expected `u32`, found `u16`
+   |                           |
+   |                           first introduced with type `u32` here
+   |
+   = note: in the same arm, a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:26:62
@@ -60,123 +88,169 @@ error[E0308]: mismatched types
 LL |     match Some((0u8, Some((1u16, 2u32)))) {
    |           ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
 LL |         Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {}
-   |                                                              ^ expected `u8`, found `u32`
+   |               - first introduced with type `u8` here         ^ expected `u8`, found `u32`
+   |
+   = note: in the same arm, a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:34:42
    |
 LL |     if let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2) {
-   |                                          ^    ---------------- this expression has type `main::Blah`
-   |                                          |
-   |                                          expected `usize`, found `isize`
+   |                          -               ^    ---------------- this expression has type `main::Blah`
+   |                          |               |
+   |                          |               expected `usize`, found `isize`
+   |                          first introduced with type `usize` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:38:47
    |
 LL |     if let Some(Blah::A(_, x, y) | Blah::B(x, y)) = Some(Blah::A(1, 1, 2)) {
-   |                                               ^     ---------------------- this expression has type `std::option::Option<main::Blah>`
-   |                                               |
-   |                                               expected `usize`, found `isize`
+   |                               -               ^     ---------------------- this expression has type `std::option::Option<main::Blah>`
+   |                               |               |
+   |                               |               expected `usize`, found `isize`
+   |                               first introduced with type `usize` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:42:22
    |
 LL |     if let (x, y) | (y, x) = (0u8, 1u16) {
-   |                      ^       ----------- this expression has type `(u8, u16)`
-   |                      |
-   |                      expected `u16`, found `u8`
+   |                -     ^       ----------- this expression has type `(u8, u16)`
+   |                |     |
+   |                |     expected `u16`, found `u8`
+   |                first introduced with type `u16` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:42:25
    |
 LL |     if let (x, y) | (y, x) = (0u8, 1u16) {
-   |                         ^    ----------- this expression has type `(u8, u16)`
-   |                         |
-   |                         expected `u8`, found `u16`
+   |             -           ^    ----------- this expression has type `(u8, u16)`
+   |             |           |
+   |             |           expected `u8`, found `u16`
+   |             first introduced with type `u8` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:47:44
    |
 LL |     if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x))))
-   |                                            ^ expected `u16`, found `u8`
+   |                           -                ^ expected `u16`, found `u8`
+   |                           |
+   |                           first introduced with type `u16` here
 ...
 LL |     = Some((0u8, Some((1u16, 2u32))))
    |       ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:47:53
    |
 LL |     if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x))))
-   |                                                     ^ expected `u8`, found `u16`
+   |                  -                                  ^ expected `u8`, found `u16`
+   |                  |
+   |                  first introduced with type `u8` here
 ...
 LL |     = Some((0u8, Some((1u16, 2u32))))
    |       ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:47:62
    |
 LL |     if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x))))
-   |                                                              ^ expected `u32`, found `u16`
+   |                              -                               ^ expected `u32`, found `u16`
+   |                              |
+   |                              first introduced with type `u32` here
 ...
 LL |     = Some((0u8, Some((1u16, 2u32))))
    |       ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:47:65
    |
 LL |     if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x))))
-   |                                                                 ^ expected `u8`, found `u32`
+   |                  - first introduced with type `u8` here         ^ expected `u8`, found `u32`
 ...
 LL |     = Some((0u8, Some((1u16, 2u32))))
    |       ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:55:39
    |
 LL |     let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2);
-   |                                       ^    ---------------- this expression has type `main::Blah`
-   |                                       |
-   |                                       expected `usize`, found `isize`
+   |                       -               ^    ---------------- this expression has type `main::Blah`
+   |                       |               |
+   |                       |               expected `usize`, found `isize`
+   |                       first introduced with type `usize` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:58:19
    |
 LL |     let (x, y) | (y, x) = (0u8, 1u16);
-   |                   ^       ----------- this expression has type `(u8, u16)`
-   |                   |
-   |                   expected `u16`, found `u8`
+   |             -     ^       ----------- this expression has type `(u8, u16)`
+   |             |     |
+   |             |     expected `u16`, found `u8`
+   |             first introduced with type `u16` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:58:22
    |
 LL |     let (x, y) | (y, x) = (0u8, 1u16);
-   |                      ^    ----------- this expression has type `(u8, u16)`
-   |                      |
-   |                      expected `u8`, found `u16`
+   |          -           ^    ----------- this expression has type `(u8, u16)`
+   |          |           |
+   |          |           expected `u8`, found `u16`
+   |          first introduced with type `u8` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:62:42
    |
 LL |     fn f1((Blah::A(_, x, y) | Blah::B(x, y)): Blah) {}
-   |                                          ^    ---- expected due to this
-   |                                          |
-   |                                          expected `usize`, found `isize`
+   |                          -               ^    ---- expected due to this
+   |                          |               |
+   |                          |               expected `usize`, found `isize`
+   |                          first introduced with type `usize` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:65:22
    |
 LL |     fn f2(((x, y) | (y, x)): (u8, u16)) {}
-   |                      ^       --------- expected due to this
-   |                      |
-   |                      expected `u16`, found `u8`
+   |                -     ^       --------- expected due to this
+   |                |     |
+   |                |     expected `u16`, found `u8`
+   |                first introduced with type `u16` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
   --> $DIR/or-patterns-binding-type-mismatch.rs:65:25
    |
 LL |     fn f2(((x, y) | (y, x)): (u8, u16)) {}
-   |                         ^    --------- expected due to this
-   |                         |
-   |                         expected `u8`, found `u16`
+   |             -           ^    --------- expected due to this
+   |             |           |
+   |             |           expected `u8`, found `u16`
+   |             first introduced with type `u8` here
+   |
+   = note: a binding must have the same type in all alternatives
 
 error: aborting due to 22 previous errors
 
diff --git a/src/test/ui/or-patterns/slice-patterns.rs b/src/test/ui/or-patterns/slice-patterns.rs
new file mode 100644
index 00000000000..05c907e8246
--- /dev/null
+++ b/src/test/ui/or-patterns/slice-patterns.rs
@@ -0,0 +1,53 @@
+// Test or-patterns with slice-patterns
+
+// run-pass
+
+#![feature(or_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum MatchArm {
+    Arm(usize),
+    Wild,
+}
+
+#[derive(Debug)]
+enum Test {
+    Foo,
+    Bar,
+    Baz,
+    Qux,
+}
+
+fn test(foo: &[Option<Test>]) -> MatchArm {
+    match foo {
+        [.., Some(Test::Qux | Test::Foo)] => MatchArm::Arm(0),
+        [Some(Test::Foo), .., Some(Test::Baz | Test::Bar)] => MatchArm::Arm(1),
+        [.., Some(Test::Bar | Test::Baz), _] => MatchArm::Arm(2),
+        _ => MatchArm::Wild,
+    }
+}
+
+fn main() {
+    let foo = vec![
+        Some(Test::Foo),
+        Some(Test::Bar),
+        Some(Test::Baz),
+        Some(Test::Qux),
+    ];
+
+    // path 1a
+    assert_eq!(test(&foo), MatchArm::Arm(0));
+    // path 1b
+    assert_eq!(test(&[Some(Test::Bar), Some(Test::Foo)]), MatchArm::Arm(0));
+    // path 2a
+    assert_eq!(test(&foo[..3]), MatchArm::Arm(1));
+    // path 2b
+    assert_eq!(test(&[Some(Test::Foo), Some(Test::Foo), Some(Test::Bar)]), MatchArm::Arm(1));
+    // path 3a
+    assert_eq!(test(&foo[1..3]), MatchArm::Arm(2));
+    // path 3b
+    assert_eq!(test(&[Some(Test::Bar), Some(Test::Baz), Some(Test::Baz), Some(Test::Bar)]),
+        MatchArm::Arm(2));
+    // path 4
+    assert_eq!(test(&foo[4..]), MatchArm::Wild);
+}