summary refs log tree commit diff
path: root/src/test/ui/pattern
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2020-10-24 22:39:51 +0200
committerGitHub <noreply@github.com>2020-10-24 22:39:51 +0200
commite12e97223f9f0bb0f2806334029aec1d9790f074 (patch)
treeea9262ad3bbd29d43864cfdb08bdbb2658d19b88 /src/test/ui/pattern
parent0a06d7344b5e83c304b926d03452f4c95d2c89dc (diff)
parentfaf87105db54a399bc598765528dec818b63a54a (diff)
downloadrust-e12e97223f9f0bb0f2806334029aec1d9790f074.tar.gz
rust-e12e97223f9f0bb0f2806334029aec1d9790f074.zip
Rollup merge of #78072 - Nadrieril:cleanup-constant-matching, r=varkor
Cleanup constant matching in exhaustiveness checking

This supercedes https://github.com/rust-lang/rust/pull/77390. I made the `Opaque` constructor work.
I have opened two issues https://github.com/rust-lang/rust/issues/78071 and https://github.com/rust-lang/rust/issues/78057 from the discussion we had on the previous PR. They are not regressions nor directly related to the current PR so I thought we'd deal with them separately.

I left a FIXME somewhere because I didn't know how to compare string constants for equality. There might even be some unicode things that need to happen there. In the meantime I preserved previous behavior.

EDIT: I accidentally fixed #78071
Diffstat (limited to 'src/test/ui/pattern')
-rw-r--r--src/test/ui/pattern/usefulness/consts-opaque.rs114
-rw-r--r--src/test/ui/pattern/usefulness/consts-opaque.stderr158
-rw-r--r--src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr4
3 files changed, 274 insertions, 2 deletions
diff --git a/src/test/ui/pattern/usefulness/consts-opaque.rs b/src/test/ui/pattern/usefulness/consts-opaque.rs
new file mode 100644
index 00000000000..f87f96e34fc
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/consts-opaque.rs
@@ -0,0 +1,114 @@
+// This file tests the exhaustiveness algorithm on opaque constants. Most of the examples give
+// unnecessary warnings because const_to_pat.rs converts a constant pattern to a wildcard when the
+// constant is not allowed as a pattern. This is an edge case so we may not care to fix it.
+// See also https://github.com/rust-lang/rust/issues/78057
+
+#![deny(unreachable_patterns)]
+
+#[derive(PartialEq)]
+struct Foo(i32);
+impl Eq for Foo {}
+const FOO: Foo = Foo(42);
+const FOO_REF: &Foo = &Foo(42);
+const FOO_REF_REF: &&Foo = &&Foo(42);
+
+#[derive(PartialEq)]
+struct Bar;
+impl Eq for Bar {}
+const BAR: Bar = Bar;
+
+#[derive(PartialEq)]
+enum Baz {
+    Baz1,
+    Baz2
+}
+impl Eq for Baz {}
+const BAZ: Baz = Baz::Baz1;
+
+type Quux = fn(usize, usize) -> usize;
+fn quux(a: usize, b: usize) -> usize { a + b }
+const QUUX: Quux = quux;
+
+fn main() {
+    match FOO {
+        FOO => {}
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        _ => {} // should not be emitting unreachable warning
+        //~^ ERROR unreachable pattern
+    }
+
+    match FOO_REF {
+        FOO_REF => {}
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        Foo(_) => {} // should not be emitting unreachable warning
+        //~^ ERROR unreachable pattern
+    }
+
+    // This used to cause an ICE (https://github.com/rust-lang/rust/issues/78071)
+    match FOO_REF_REF {
+        FOO_REF_REF => {}
+        //~^ WARNING must be annotated with `#[derive(PartialEq, Eq)]`
+        //~| WARNING this was previously accepted by the compiler but is being phased out
+        Foo(_) => {}
+    }
+
+    match BAR {
+        Bar => {}
+        BAR => {} // should not be emitting unreachable warning
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        //~| ERROR unreachable pattern
+        _ => {}
+        //~^ ERROR unreachable pattern
+    }
+
+    match BAR {
+        BAR => {}
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        Bar => {} // should not be emitting unreachable warning
+        //~^ ERROR unreachable pattern
+        _ => {}
+        //~^ ERROR unreachable pattern
+    }
+
+    match BAR {
+        BAR => {}
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        BAR => {} // should not be emitting unreachable warning
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        //~| ERROR unreachable pattern
+        _ => {} // should not be emitting unreachable warning
+        //~^ ERROR unreachable pattern
+    }
+
+    match BAZ {
+        BAZ => {}
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        Baz::Baz1 => {} // should not be emitting unreachable warning
+        //~^ ERROR unreachable pattern
+        _ => {}
+        //~^ ERROR unreachable pattern
+    }
+
+    match BAZ {
+        Baz::Baz1 => {}
+        BAZ => {}
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        _ => {}
+        //~^ ERROR unreachable pattern
+    }
+
+    match BAZ {
+        BAZ => {}
+        //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
+        Baz::Baz2 => {} // should not be emitting unreachable warning
+        //~^ ERROR unreachable pattern
+        _ => {} // should not be emitting unreachable warning
+        //~^ ERROR unreachable pattern
+    }
+
+    match QUUX {
+        QUUX => {}
+        QUUX => {}
+        _ => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/consts-opaque.stderr b/src/test/ui/pattern/usefulness/consts-opaque.stderr
new file mode 100644
index 00000000000..f10166d5a35
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/consts-opaque.stderr
@@ -0,0 +1,158 @@
+error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:34:9
+   |
+LL |         FOO => {}
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:36:9
+   |
+LL |         _ => {} // should not be emitting unreachable warning
+   |         ^
+   |
+note: the lint level is defined here
+  --> $DIR/consts-opaque.rs:6:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:41:9
+   |
+LL |         FOO_REF => {}
+   |         ^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:43:9
+   |
+LL |         Foo(_) => {} // should not be emitting unreachable warning
+   |         ^^^^^^
+
+warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:49:9
+   |
+LL |         FOO_REF_REF => {}
+   |         ^^^^^^^^^^^
+   |
+   = note: `#[warn(indirect_structural_match)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+
+error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:57:9
+   |
+LL |         BAR => {} // should not be emitting unreachable warning
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:57:9
+   |
+LL |         Bar => {}
+   |         --- matches any value
+LL |         BAR => {} // should not be emitting unreachable warning
+   |         ^^^ unreachable pattern
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:60:9
+   |
+LL |         Bar => {}
+   |         --- matches any value
+...
+LL |         _ => {}
+   |         ^ unreachable pattern
+
+error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:65:9
+   |
+LL |         BAR => {}
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:67:9
+   |
+LL |         Bar => {} // should not be emitting unreachable warning
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:69:9
+   |
+LL |         Bar => {} // should not be emitting unreachable warning
+   |         --- matches any value
+LL |
+LL |         _ => {}
+   |         ^ unreachable pattern
+
+error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:74:9
+   |
+LL |         BAR => {}
+   |         ^^^
+
+error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:76:9
+   |
+LL |         BAR => {} // should not be emitting unreachable warning
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:76:9
+   |
+LL |         BAR => {} // should not be emitting unreachable warning
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:79:9
+   |
+LL |         _ => {} // should not be emitting unreachable warning
+   |         ^
+
+error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:84:9
+   |
+LL |         BAZ => {}
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:86:9
+   |
+LL |         Baz::Baz1 => {} // should not be emitting unreachable warning
+   |         ^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:88:9
+   |
+LL |         _ => {}
+   |         ^
+
+error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:94:9
+   |
+LL |         BAZ => {}
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:96:9
+   |
+LL |         _ => {}
+   |         ^
+
+error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
+  --> $DIR/consts-opaque.rs:101:9
+   |
+LL |         BAZ => {}
+   |         ^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:103:9
+   |
+LL |         Baz::Baz2 => {} // should not be emitting unreachable warning
+   |         ^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/consts-opaque.rs:105:9
+   |
+LL |         _ => {} // should not be emitting unreachable warning
+   |         ^
+
+error: aborting due to 22 previous errors; 1 warning emitted
+
diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
index ffc8433403f..7968f9713ff 100644
--- a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
+++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
@@ -7,11 +7,11 @@ LL |     match buf {
    = 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; 4]`
 
-error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 2 more not covered
+error[E0004]: non-exhaustive patterns: `&[0_u8..=64_u8, _, _, _]` and `&[66_u8..=u8::MAX, _, _, _]` not covered
   --> $DIR/match-byte-array-patterns-2.rs:10:11
    |
 LL |     match buf {
-   |           ^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 2 more not covered
+   |           ^^^ patterns `&[0_u8..=64_u8, _, _, _]` and `&[66_u8..=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]`