about summary refs log tree commit diff
path: root/src/test/ui/or-patterns
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-02-14 23:11:03 +0000
committerbors <bors@rust-lang.org>2020-02-14 23:11:03 +0000
commitb92c6ee882853313698f1148512e8e992ba36b2d (patch)
tree8932cd3cddd9fe9a5c99eab6fae97fb7bf435e99 /src/test/ui/or-patterns
parent433aae93e4ef866a1fdfefad136b32ed89acd3e7 (diff)
parenta6ff1dbaa4c0ec5a75e6cfedf289ebd0bc66ae67 (diff)
downloadrust-b92c6ee882853313698f1148512e8e992ba36b2d.tar.gz
rust-b92c6ee882853313698f1148512e8e992ba36b2d.zip
Auto merge of #69172 - JohnTitor:rollup-6cbmwcw, r=JohnTitor
Rollup of 7 pull requests

Successful merges:

 - #68129 (Correct inference of primitive operand type behind binary operation)
 - #68475 (Use a `ParamEnvAnd<Predicate>` for caching in `ObligationForest`)
 - #68856 (typeck: clarify def_bm adjustments & add tests for or-patterns)
 - #69051 (simplify_try: address some of eddyb's comments)
 - #69128 (Fix extra subslice lowering)
 - #69150 (Follow-up to #68848)
 - #69164 (Update pulldown-cmark dependency)

Failed merges:

r? @ghost
Diffstat (limited to 'src/test/ui/or-patterns')
-rw-r--r--src/test/ui/or-patterns/or-pattern-mismatch.rs4
-rw-r--r--src/test/ui/or-patterns/or-pattern-mismatch.stderr9
-rw-r--r--src/test/ui/or-patterns/or-patterns-binding-type-mismatch.rs68
-rw-r--r--src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr183
-rw-r--r--src/test/ui/or-patterns/or-patterns-default-binding-modes.rs132
5 files changed, 383 insertions, 13 deletions
diff --git a/src/test/ui/or-patterns/or-pattern-mismatch.rs b/src/test/ui/or-patterns/or-pattern-mismatch.rs
deleted file mode 100644
index 973954bca5a..00000000000
--- a/src/test/ui/or-patterns/or-pattern-mismatch.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-enum Blah { A(isize, isize, usize), B(isize, isize) }
-
-fn main() { match Blah::A(1, 1, 2) { Blah::A(_, x, y) | Blah::B(x, y) => { } } }
-//~^ ERROR mismatched types
diff --git a/src/test/ui/or-patterns/or-pattern-mismatch.stderr b/src/test/ui/or-patterns/or-pattern-mismatch.stderr
deleted file mode 100644
index bc288e06250..00000000000
--- a/src/test/ui/or-patterns/or-pattern-mismatch.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/or-pattern-mismatch.rs:3:68
-   |
-LL | fn main() { match Blah::A(1, 1, 2) { Blah::A(_, x, y) | Blah::B(x, y) => { } } }
-   |                   ---------------- this expression has type `Blah` ^ expected `usize`, found `isize`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.rs b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.rs
new file mode 100644
index 00000000000..5ec7dc6962c
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.rs
@@ -0,0 +1,68 @@
+// Here we test type checking of bindings when combined with or-patterns.
+// Specifically, we ensure that introducing bindings of different types result in type errors.
+
+#![feature(or_patterns)]
+
+fn main() {
+    enum Blah {
+        A(isize, isize, usize),
+        B(isize, isize),
+    }
+
+    match Blah::A(1, 1, 2) {
+        Blah::A(_, x, y) | Blah::B(x, y) => {} //~ ERROR mismatched types
+    }
+
+    match Some(Blah::A(1, 1, 2)) {
+        Some(Blah::A(_, x, y) | Blah::B(x, y)) => {} //~ ERROR mismatched types
+    }
+
+    match (0u8, 1u16) {
+        (x, y) | (y, x) => {} //~ ERROR mismatched types
+                              //~^ ERROR mismatched types
+    }
+
+    match Some((0u8, Some((1u16, 2u32)))) {
+        Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {}
+        //~^ ERROR mismatched types
+        //~| ERROR mismatched types
+        //~| ERROR mismatched types
+        //~| ERROR mismatched types
+        _ => {}
+    }
+
+    if let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2) {
+        //~^ ERROR mismatched types
+    }
+
+    if let Some(Blah::A(_, x, y) | Blah::B(x, y)) = Some(Blah::A(1, 1, 2)) {
+        //~^ ERROR mismatched types
+    }
+
+    if let (x, y) | (y, x) = (0u8, 1u16) {
+        //~^ ERROR mismatched types
+        //~| ERROR mismatched types
+    }
+
+    if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x))))
+        //~^ ERROR mismatched types
+        //~| ERROR mismatched types
+        //~| ERROR mismatched types
+        //~| ERROR mismatched types
+    = Some((0u8, Some((1u16, 2u32))))
+    {}
+
+    let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2);
+    //~^ ERROR mismatched types
+
+    let (x, y) | (y, x) = (0u8, 1u16);
+    //~^ ERROR mismatched types
+    //~| ERROR mismatched types
+
+    fn f1((Blah::A(_, x, y) | Blah::B(x, y)): Blah) {}
+    //~^ ERROR mismatched types
+
+    fn f2(((x, y) | (y, x)): (u8, u16)) {}
+    //~^ ERROR mismatched types
+    //~| ERROR mismatched types
+}
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
new file mode 100644
index 00000000000..5094f04b920
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr
@@ -0,0 +1,183 @@
+error[E0308]: mismatched types
+  --> $DIR/or-patterns-binding-type-mismatch.rs:13:39
+   |
+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`
+
+error[E0308]: mismatched types
+  --> $DIR/or-patterns-binding-type-mismatch.rs:17:44
+   |
+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`
+
+error[E0308]: mismatched types
+  --> $DIR/or-patterns-binding-type-mismatch.rs:21:19
+   |
+LL |     match (0u8, 1u16) {
+   |           ----------- this expression has type `(u8, u16)`
+LL |         (x, y) | (y, x) => {}
+   |                   ^ expected `u16`, found `u8`
+
+error[E0308]: mismatched types
+  --> $DIR/or-patterns-binding-type-mismatch.rs:21:22
+   |
+LL |     match (0u8, 1u16) {
+   |           ----------- this expression has type `(u8, u16)`
+LL |         (x, y) | (y, x) => {}
+   |                      ^ expected `u8`, found `u16`
+
+error[E0308]: mismatched types
+  --> $DIR/or-patterns-binding-type-mismatch.rs:26:41
+   |
+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`
+
+error[E0308]: mismatched types
+  --> $DIR/or-patterns-binding-type-mismatch.rs:26:50
+   |
+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`
+
+error[E0308]: mismatched types
+  --> $DIR/or-patterns-binding-type-mismatch.rs:26:59
+   |
+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`
+
+error[E0308]: mismatched types
+  --> $DIR/or-patterns-binding-type-mismatch.rs:26:62
+   |
+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`
+
+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`
+
+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`
+
+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`
+
+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`
+
+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`
+...
+LL |     = Some((0u8, Some((1u16, 2u32))))
+   |       ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
+
+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`
+...
+LL |     = Some((0u8, Some((1u16, 2u32))))
+   |       ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
+
+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`
+...
+LL |     = Some((0u8, Some((1u16, 2u32))))
+   |       ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
+
+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`
+...
+LL |     = Some((0u8, Some((1u16, 2u32))))
+   |       ------------------------------- this expression has type `std::option::Option<(u8, std::option::Option<(u16, u32)>)>`
+
+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`
+
+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`
+
+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`
+
+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`
+
+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`
+
+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`
+
+error: aborting due to 22 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/or-patterns/or-patterns-default-binding-modes.rs b/src/test/ui/or-patterns/or-patterns-default-binding-modes.rs
new file mode 100644
index 00000000000..3b6047c7be4
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-default-binding-modes.rs
@@ -0,0 +1,132 @@
+// Test that or-patterns are pass-through with respect to default binding modes.
+
+// check-pass
+
+#![feature(or_patterns)]
+#![allow(irrefutable_let_patterns)]
+
+fn main() {
+    // A regression test for a mistake we made at one point:
+    match &1 {
+        e @ &(1..=2) | e @ &(3..=4) => {}
+        _ => {}
+    }
+
+    match &0 {
+        0 | &1 => {}
+        _ => {}
+    }
+
+    type R<'a> = &'a Result<u8, u8>;
+
+    let res: R<'_> = &Ok(0);
+
+    match res {
+        // Alternatives propagate expected type / binding mode independently.
+        Ok(mut x) | &Err(mut x) => drop::<u8>(x),
+    }
+    match res {
+        &(Ok(x) | Err(x)) => drop::<u8>(x),
+    }
+    match res {
+        Ok(x) | Err(x) => drop::<&u8>(x),
+    }
+    if let Ok(mut x) | &Err(mut x) = res {
+        drop::<u8>(x);
+    }
+    if let &(Ok(x) | Err(x)) = res {
+        drop::<u8>(x);
+    }
+    let Ok(mut x) | &Err(mut x) = res;
+    drop::<u8>(x);
+    let &(Ok(x) | Err(x)) = res;
+    drop::<u8>(x);
+    let Ok(x) | Err(x) = res;
+    drop::<&u8>(x);
+    for Ok(mut x) | &Err(mut x) in std::iter::once(res) {
+        drop::<u8>(x);
+    }
+    for &(Ok(x) | Err(x)) in std::iter::once(res) {
+        drop::<u8>(x);
+    }
+    for Ok(x) | Err(x) in std::iter::once(res) {
+        drop::<&u8>(x);
+    }
+    fn f1((Ok(mut x) | &Err(mut x)): R<'_>) {
+        drop::<u8>(x);
+    }
+    fn f2(&(Ok(x) | Err(x)): R<'_>) {
+        drop::<u8>(x);
+    }
+    fn f3((Ok(x) | Err(x)): R<'_>) {
+        drop::<&u8>(x);
+    }
+
+    // Wrap inside another type (a product for a simplity with irrefutable contexts).
+    #[derive(Copy, Clone)]
+    struct Wrap<T>(T);
+    let wres = Wrap(res);
+
+    match wres {
+        Wrap(Ok(mut x) | &Err(mut x)) => drop::<u8>(x),
+    }
+    match wres {
+        Wrap(&(Ok(x) | Err(x))) => drop::<u8>(x),
+    }
+    match wres {
+        Wrap(Ok(x) | Err(x)) => drop::<&u8>(x),
+    }
+    if let Wrap(Ok(mut x) | &Err(mut x)) = wres {
+        drop::<u8>(x);
+    }
+    if let Wrap(&(Ok(x) | Err(x))) = wres {
+        drop::<u8>(x);
+    }
+    if let Wrap(Ok(x) | Err(x)) = wres {
+        drop::<&u8>(x);
+    }
+    let Wrap(Ok(mut x) | &Err(mut x)) = wres;
+    drop::<u8>(x);
+    let Wrap(&(Ok(x) | Err(x))) = wres;
+    drop::<u8>(x);
+    let Wrap(Ok(x) | Err(x)) = wres;
+    drop::<&u8>(x);
+    for Wrap(Ok(mut x) | &Err(mut x)) in std::iter::once(wres) {
+        drop::<u8>(x);
+    }
+    for Wrap(&(Ok(x) | Err(x))) in std::iter::once(wres) {
+        drop::<u8>(x);
+    }
+    for Wrap(Ok(x) | Err(x)) in std::iter::once(wres) {
+        drop::<&u8>(x);
+    }
+    fn fw1(Wrap(Ok(mut x) | &Err(mut x)): Wrap<R<'_>>) {
+        drop::<u8>(x);
+    }
+    fn fw2(Wrap(&(Ok(x) | Err(x))): Wrap<R<'_>>) {
+        drop::<u8>(x);
+    }
+    fn fw3(Wrap(Ok(x) | Err(x)): Wrap<R<'_>>) {
+        drop::<&u8>(x);
+    }
+
+    // Nest some more:
+
+    enum Tri<P> {
+        A(P),
+        B(P),
+        C(P),
+    }
+
+    let tri = &Tri::A(&Ok(0));
+    let Tri::A(Ok(mut x) | Err(mut x))
+    | Tri::B(&Ok(mut x) | Err(mut x))
+    | &Tri::C(Ok(mut x) | Err(mut x)) = tri;
+    drop::<u8>(x);
+
+    match tri {
+        Tri::A(Ok(mut x) | Err(mut x))
+        | Tri::B(&Ok(mut x) | Err(mut x))
+        | &Tri::C(Ok(mut x) | Err(mut x)) => drop::<u8>(x),
+    }
+}