summaryrefslogtreecommitdiffstats
path: root/src/test/ui/match
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/match')
-rw-r--r--src/test/ui/match/auxiliary/match_non_exhaustive_lib.rs5
-rw-r--r--src/test/ui/match/const_non_normal_zst_ref_pattern.rs9
-rw-r--r--src/test/ui/match/expr-match-panic-fn.rs19
-rw-r--r--src/test/ui/match/expr-match-panic.rs10
-rw-r--r--src/test/ui/match/expr_before_ident_pat.rs15
-rw-r--r--src/test/ui/match/expr_before_ident_pat.stderr15
-rw-r--r--src/test/ui/match/guards.rs20
-rw-r--r--src/test/ui/match/issue-11319.rs13
-rw-r--r--src/test/ui/match/issue-11319.stderr21
-rw-r--r--src/test/ui/match/issue-11940.rs11
-rw-r--r--src/test/ui/match/issue-18060.rs8
-rw-r--r--src/test/ui/match/issue-26251.rs15
-rw-r--r--src/test/ui/match/issue-26996.rs24
-rw-r--r--src/test/ui/match/issue-27021.rs28
-rw-r--r--src/test/ui/match/issue-33498.rs11
-rw-r--r--src/test/ui/match/issue-41255.rs51
-rw-r--r--src/test/ui/match/issue-41255.stderr115
-rw-r--r--src/test/ui/match/issue-42679.rs22
-rw-r--r--src/test/ui/match/issue-46920-byte-array-patterns.rs28
-rw-r--r--src/test/ui/match/issue-56685.rs44
-rw-r--r--src/test/ui/match/issue-56685.stderr63
-rw-r--r--src/test/ui/match/issue-70972-dyn-trait.rs10
-rw-r--r--src/test/ui/match/issue-70972-dyn-trait.stderr8
-rw-r--r--src/test/ui/match/issue-72680.rs63
-rw-r--r--src/test/ui/match/issue-72896.rs23
-rw-r--r--src/test/ui/match/issue-74050-end-span.rs13
-rw-r--r--src/test/ui/match/issue-74050-end-span.stderr15
-rw-r--r--src/test/ui/match/issue-82392.rs9
-rw-r--r--src/test/ui/match/issue-82392.stdout16
-rw-r--r--src/test/ui/match/issue-82866.rs7
-rw-r--r--src/test/ui/match/issue-82866.stderr16
-rw-r--r--src/test/ui/match/issue-84434.rs18
-rw-r--r--src/test/ui/match/issue-91058.rs11
-rw-r--r--src/test/ui/match/issue-91058.stderr11
-rw-r--r--src/test/ui/match/issue-92100.rs7
-rw-r--r--src/test/ui/match/issue-92100.stderr9
-rw-r--r--src/test/ui/match/match-arm-resolving-to-never.rs19
-rw-r--r--src/test/ui/match/match-arm-resolving-to-never.stderr18
-rw-r--r--src/test/ui/match/match-bot-panic.rs16
-rw-r--r--src/test/ui/match/match-disc-bot.rs16
-rw-r--r--src/test/ui/match/match-fn-call.rs12
-rw-r--r--src/test/ui/match/match-fn-call.stderr19
-rw-r--r--src/test/ui/match/match-ill-type2.rs7
-rw-r--r--src/test/ui/match/match-ill-type2.stderr12
-rw-r--r--src/test/ui/match/match-incompat-type-semi.rs52
-rw-r--r--src/test/ui/match/match-incompat-type-semi.stderr88
-rw-r--r--src/test/ui/match/match-join.rs11
-rw-r--r--src/test/ui/match/match-join.stderr9
-rw-r--r--src/test/ui/match/match-no-arms-unreachable-after.rs12
-rw-r--r--src/test/ui/match/match-no-arms-unreachable-after.stderr16
-rw-r--r--src/test/ui/match/match-on-negative-integer-ranges.rs7
-rw-r--r--src/test/ui/match/match-pattern-field-mismatch-2.rs16
-rw-r--r--src/test/ui/match/match-pattern-field-mismatch-2.stderr12
-rw-r--r--src/test/ui/match/match-pattern-field-mismatch.rs16
-rw-r--r--src/test/ui/match/match-pattern-field-mismatch.stderr21
-rw-r--r--src/test/ui/match/match-range-fail-2.rs24
-rw-r--r--src/test/ui/match/match-range-fail-2.stderr40
-rw-r--r--src/test/ui/match/match-range-fail.rs22
-rw-r--r--src/test/ui/match/match-range-fail.stderr40
-rw-r--r--src/test/ui/match/match-ref-mut-invariance.rs15
-rw-r--r--src/test/ui/match/match-ref-mut-invariance.stderr17
-rw-r--r--src/test/ui/match/match-ref-mut-let-invariance.rs16
-rw-r--r--src/test/ui/match/match-ref-mut-let-invariance.stderr18
-rw-r--r--src/test/ui/match/match-ref-mut-stability.rs37
-rw-r--r--src/test/ui/match/match-struct.rs11
-rw-r--r--src/test/ui/match/match-struct.stderr11
-rw-r--r--src/test/ui/match/match-tag-nullary.rs4
-rw-r--r--src/test/ui/match/match-tag-nullary.stderr14
-rw-r--r--src/test/ui/match/match-tag-unary.rs4
-rw-r--r--src/test/ui/match/match-tag-unary.stderr11
-rw-r--r--src/test/ui/match/match-type-err-first-arm.rs50
-rw-r--r--src/test/ui/match/match-type-err-first-arm.stderr65
-rw-r--r--src/test/ui/match/match-unresolved-one-arm.rs7
-rw-r--r--src/test/ui/match/match-unresolved-one-arm.stderr14
-rw-r--r--src/test/ui/match/match-vec-mismatch-2.rs6
-rw-r--r--src/test/ui/match/match-vec-mismatch-2.stderr9
-rw-r--r--src/test/ui/match/match-wildcards.rs21
-rw-r--r--src/test/ui/match/match_non_exhaustive.rs32
-rw-r--r--src/test/ui/match/match_non_exhaustive.stderr56
-rw-r--r--src/test/ui/match/pattern-deref-miscompile.rs46
80 files changed, 1752 insertions, 0 deletions
diff --git a/src/test/ui/match/auxiliary/match_non_exhaustive_lib.rs b/src/test/ui/match/auxiliary/match_non_exhaustive_lib.rs
new file mode 100644
index 000000000..3be72551e
--- /dev/null
+++ b/src/test/ui/match/auxiliary/match_non_exhaustive_lib.rs
@@ -0,0 +1,5 @@
+#[non_exhaustive]
+pub enum E1 {}
+
+#[non_exhaustive]
+pub enum E2 { A, B }
diff --git a/src/test/ui/match/const_non_normal_zst_ref_pattern.rs b/src/test/ui/match/const_non_normal_zst_ref_pattern.rs
new file mode 100644
index 000000000..a114fafb6
--- /dev/null
+++ b/src/test/ui/match/const_non_normal_zst_ref_pattern.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+const FOO: isize = 10;
+const ZST: &() = unsafe { std::mem::transmute(FOO) };
+fn main() {
+ match &() {
+ ZST => 9,
+ };
+}
diff --git a/src/test/ui/match/expr-match-panic-fn.rs b/src/test/ui/match/expr-match-panic-fn.rs
new file mode 100644
index 000000000..ea471717e
--- /dev/null
+++ b/src/test/ui/match/expr-match-panic-fn.rs
@@ -0,0 +1,19 @@
+// run-fail
+// error-pattern:explicit panic
+// ignore-emscripten no processes
+
+fn f() -> ! {
+ panic!()
+}
+
+fn g() -> isize {
+ let x = match true {
+ true => f(),
+ false => 10,
+ };
+ return x;
+}
+
+fn main() {
+ g();
+}
diff --git a/src/test/ui/match/expr-match-panic.rs b/src/test/ui/match/expr-match-panic.rs
new file mode 100644
index 000000000..53f8a8bd3
--- /dev/null
+++ b/src/test/ui/match/expr-match-panic.rs
@@ -0,0 +1,10 @@
+// run-fail
+// error-pattern:explicit panic
+// ignore-emscripten no processes
+
+fn main() {
+ let _x = match true {
+ false => 0,
+ true => panic!(),
+ };
+}
diff --git a/src/test/ui/match/expr_before_ident_pat.rs b/src/test/ui/match/expr_before_ident_pat.rs
new file mode 100644
index 000000000..47db6c3f4
--- /dev/null
+++ b/src/test/ui/match/expr_before_ident_pat.rs
@@ -0,0 +1,15 @@
+#![feature(half_open_range_patterns)]
+
+macro_rules! funny {
+ ($a:expr, $b:ident) => {
+ match [1, 2] {
+ [$a, $b] => {}
+ }
+ };
+}
+
+fn main() {
+ funny!(a, a);
+ //~^ ERROR cannot find value `a` in this scope
+ //~| ERROR arbitrary expressions aren't allowed in patterns
+}
diff --git a/src/test/ui/match/expr_before_ident_pat.stderr b/src/test/ui/match/expr_before_ident_pat.stderr
new file mode 100644
index 000000000..2bd1b3b94
--- /dev/null
+++ b/src/test/ui/match/expr_before_ident_pat.stderr
@@ -0,0 +1,15 @@
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/expr_before_ident_pat.rs:12:12
+ |
+LL | funny!(a, a);
+ | ^ not found in this scope
+
+error: arbitrary expressions aren't allowed in patterns
+ --> $DIR/expr_before_ident_pat.rs:12:12
+ |
+LL | funny!(a, a);
+ | ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/match/guards.rs b/src/test/ui/match/guards.rs
new file mode 100644
index 000000000..10a4bb673
--- /dev/null
+++ b/src/test/ui/match/guards.rs
@@ -0,0 +1,20 @@
+// run-pass
+
+#![allow(non_shorthand_field_patterns)]
+
+#[derive(Copy, Clone)]
+struct Pair { x: isize, y: isize }
+
+pub fn main() {
+ let a: isize =
+ match 10 { x if x < 7 => { 1 } x if x < 11 => { 2 } 10 => { 3 } _ => { 4 } };
+ assert_eq!(a, 2);
+
+ let b: isize =
+ match (Pair {x: 10, y: 20}) {
+ x if x.x < 5 && x.y < 5 => { 1 }
+ Pair {x: x, y: y} if x == 10 && y == 20 => { 2 }
+ Pair {x: _x, y: _y} => { 3 }
+ };
+ assert_eq!(b, 2);
+}
diff --git a/src/test/ui/match/issue-11319.rs b/src/test/ui/match/issue-11319.rs
new file mode 100644
index 000000000..ab69ab250
--- /dev/null
+++ b/src/test/ui/match/issue-11319.rs
@@ -0,0 +1,13 @@
+fn main() {
+ match Some(10) {
+ //~^ NOTE `match` arms have incompatible types
+ Some(5) => false,
+ //~^ NOTE this is found to be of type `bool`
+ Some(2) => true,
+ //~^ NOTE this is found to be of type `bool`
+ None => (),
+ //~^ ERROR `match` arms have incompatible types
+ //~| NOTE expected `bool`, found `()`
+ _ => true
+ }
+}
diff --git a/src/test/ui/match/issue-11319.stderr b/src/test/ui/match/issue-11319.stderr
new file mode 100644
index 000000000..fc44205e8
--- /dev/null
+++ b/src/test/ui/match/issue-11319.stderr
@@ -0,0 +1,21 @@
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/issue-11319.rs:8:20
+ |
+LL | / match Some(10) {
+LL | |
+LL | | Some(5) => false,
+ | | ----- this is found to be of type `bool`
+LL | |
+LL | | Some(2) => true,
+ | | ---- this is found to be of type `bool`
+LL | |
+LL | | None => (),
+ | | ^^ expected `bool`, found `()`
+... |
+LL | | _ => true
+LL | | }
+ | |_____- `match` arms have incompatible types
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/match/issue-11940.rs b/src/test/ui/match/issue-11940.rs
new file mode 100644
index 000000000..6815c87ed
--- /dev/null
+++ b/src/test/ui/match/issue-11940.rs
@@ -0,0 +1,11 @@
+// run-pass
+
+const TEST_STR: &'static str = "abcd";
+
+fn main() {
+ let s = "abcd";
+ match s {
+ TEST_STR => (),
+ _ => unreachable!()
+ }
+}
diff --git a/src/test/ui/match/issue-18060.rs b/src/test/ui/match/issue-18060.rs
new file mode 100644
index 000000000..b5f3d0f74
--- /dev/null
+++ b/src/test/ui/match/issue-18060.rs
@@ -0,0 +1,8 @@
+// run-pass
+// Regression test for #18060: match arms were matching in the wrong order.
+
+fn main() {
+ assert_eq!(2, match (1, 3) { (0, 2..=5) => 1, (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 });
+ assert_eq!(2, match (1, 3) { (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 });
+ assert_eq!(2, match (1, 7) { (0, 2..=5) => 1, (1, 7) => 2, (_, 2..=5) => 3, (_, _) => 4 });
+}
diff --git a/src/test/ui/match/issue-26251.rs b/src/test/ui/match/issue-26251.rs
new file mode 100644
index 000000000..a3e26a412
--- /dev/null
+++ b/src/test/ui/match/issue-26251.rs
@@ -0,0 +1,15 @@
+// run-pass
+#![allow(overlapping_range_endpoints)]
+
+fn main() {
+ let x = 'a';
+
+ let y = match x {
+ 'a'..='b' if false => "one",
+ 'a' => "two",
+ 'a'..='b' => "three",
+ _ => panic!("what?"),
+ };
+
+ assert_eq!(y, "two");
+}
diff --git a/src/test/ui/match/issue-26996.rs b/src/test/ui/match/issue-26996.rs
new file mode 100644
index 000000000..84037b72a
--- /dev/null
+++ b/src/test/ui/match/issue-26996.rs
@@ -0,0 +1,24 @@
+// run-pass
+
+// This test is bogus (i.e., should be check-fail) during the period
+// where #54986 is implemented and #54987 is *not* implemented. For
+// now: just ignore it
+//
+// ignore-test
+
+// This test is checking that the write to `c.0` (which has been moved out of)
+// won't overwrite the state in `c2`.
+//
+// That's a fine thing to test when this code is accepted by the
+// compiler, and this code is being transcribed accordingly into
+// the ui test issue-21232-partial-init-and-use.rs
+
+fn main() {
+ let mut c = (1, "".to_owned());
+ match c {
+ c2 => {
+ c.0 = 2;
+ assert_eq!(c2.0, 1);
+ }
+ }
+}
diff --git a/src/test/ui/match/issue-27021.rs b/src/test/ui/match/issue-27021.rs
new file mode 100644
index 000000000..ef3b114a5
--- /dev/null
+++ b/src/test/ui/match/issue-27021.rs
@@ -0,0 +1,28 @@
+// run-pass
+
+// This test is bogus (i.e., should be check-fail) during the period
+// where #54986 is implemented and #54987 is *not* implemented. For
+// now: just ignore it
+//
+// ignore-test
+
+// These are variants of issue-26996.rs. In all cases we are writing
+// into a record field that has been moved out of, and ensuring that
+// such a write won't overwrite the state of the thing it was moved
+// into.
+//
+// That's a fine thing to test when this code is accepted by the
+// compiler, and this code is being transcribed accordingly into
+// the ui test issue-21232-partial-init-and-use.rs
+
+fn main() {
+ let mut c = (1, (1, "".to_owned()));
+ match c {
+ c2 => { (c.1).0 = 2; assert_eq!((c2.1).0, 1); }
+ }
+
+ let mut c = (1, (1, (1, "".to_owned())));
+ match c.1 {
+ c2 => { ((c.1).1).0 = 3; assert_eq!((c2.1).0, 1); }
+ }
+}
diff --git a/src/test/ui/match/issue-33498.rs b/src/test/ui/match/issue-33498.rs
new file mode 100644
index 000000000..9c8a97e7e
--- /dev/null
+++ b/src/test/ui/match/issue-33498.rs
@@ -0,0 +1,11 @@
+// run-pass
+#![allow(unused_variables)]
+pub fn main() {
+ let x = (0, 2);
+
+ match x {
+ (0, ref y) => {}
+ (y, 0) => {}
+ _ => (),
+ }
+}
diff --git a/src/test/ui/match/issue-41255.rs b/src/test/ui/match/issue-41255.rs
new file mode 100644
index 000000000..9d7072f16
--- /dev/null
+++ b/src/test/ui/match/issue-41255.rs
@@ -0,0 +1,51 @@
+// Matching against float literals should result in a linter error
+
+#![feature(exclusive_range_pattern)]
+#![feature(half_open_range_patterns)]
+#![allow(unused)]
+#![forbid(illegal_floating_point_literal_pattern)]
+
+fn main() {
+ let x = 42.0;
+ match x {
+ 5.0 => {}, //~ ERROR floating-point types cannot be used in patterns
+ //~| WARNING hard error
+ 5.0f32 => {}, //~ ERROR floating-point types cannot be used in patterns
+ //~| WARNING hard error
+ -5.0 => {}, //~ ERROR floating-point types cannot be used in patterns
+ //~| WARNING hard error
+ 1.0 .. 33.0 => {}, //~ ERROR floating-point types cannot be used in patterns
+ //~| WARNING hard error
+ //~| ERROR floating-point types cannot be used in patterns
+ //~| WARNING hard error
+ 39.0 ..= 70.0 => {}, //~ ERROR floating-point types cannot be used in patterns
+ //~| ERROR floating-point types cannot be used in patterns
+ //~| WARNING hard error
+ //~| WARNING hard error
+
+ ..71.0 => {}
+ //~^ ERROR floating-point types cannot be used in patterns
+ //~| WARNING this was previously accepted by the compiler
+ ..=72.0 => {}
+ //~^ ERROR floating-point types cannot be used in patterns
+ //~| WARNING this was previously accepted by the compiler
+ 71.0.. => {}
+ //~^ ERROR floating-point types cannot be used in patterns
+ //~| WARNING this was previously accepted by the compiler
+ _ => {},
+ };
+ let y = 5.0;
+ // Same for tuples
+ match (x, 5) {
+ (3.14, 1) => {}, //~ ERROR floating-point types cannot be used
+ //~| WARNING hard error
+ _ => {},
+ }
+ // Or structs
+ struct Foo { x: f32 };
+ match (Foo { x }) {
+ Foo { x: 2.0 } => {}, //~ ERROR floating-point types cannot be used
+ //~| WARNING hard error
+ _ => {},
+ }
+}
diff --git a/src/test/ui/match/issue-41255.stderr b/src/test/ui/match/issue-41255.stderr
new file mode 100644
index 000000000..bf81c8d37
--- /dev/null
+++ b/src/test/ui/match/issue-41255.stderr
@@ -0,0 +1,115 @@
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:11:9
+ |
+LL | 5.0 => {},
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-41255.rs:6:11
+ |
+LL | #![forbid(illegal_floating_point_literal_pattern)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:13:9
+ |
+LL | 5.0f32 => {},
+ | ^^^^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:15:10
+ |
+LL | -5.0 => {},
+ | ^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:17:9
+ |
+LL | 1.0 .. 33.0 => {},
+ | ^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:17:16
+ |
+LL | 1.0 .. 33.0 => {},
+ | ^^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:21:9
+ |
+LL | 39.0 ..= 70.0 => {},
+ | ^^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:21:18
+ |
+LL | 39.0 ..= 70.0 => {},
+ | ^^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:26:11
+ |
+LL | ..71.0 => {}
+ | ^^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:29:12
+ |
+LL | ..=72.0 => {}
+ | ^^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:32:9
+ |
+LL | 71.0.. => {}
+ | ^^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:40:10
+ |
+LL | (3.14, 1) => {},
+ | ^^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: floating-point types cannot be used in patterns
+ --> $DIR/issue-41255.rs:47:18
+ |
+LL | Foo { x: 2.0 } => {},
+ | ^^^
+ |
+ = 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 #41620 <https://github.com/rust-lang/rust/issues/41620>
+
+error: aborting due to 12 previous errors
+
diff --git a/src/test/ui/match/issue-42679.rs b/src/test/ui/match/issue-42679.rs
new file mode 100644
index 000000000..596309f25
--- /dev/null
+++ b/src/test/ui/match/issue-42679.rs
@@ -0,0 +1,22 @@
+// run-pass
+#![feature(box_syntax)]
+#![feature(box_patterns)]
+
+#[derive(Debug, PartialEq)]
+enum Test {
+ Foo(usize),
+ Bar(isize),
+}
+
+fn main() {
+ let a = box Test::Foo(10);
+ let b = box Test::Bar(-20);
+ match (a, b) {
+ (_, box Test::Foo(_)) => unreachable!(),
+ (box Test::Foo(x), b) => {
+ assert_eq!(x, 10);
+ assert_eq!(b, box Test::Bar(-20));
+ },
+ _ => unreachable!(),
+ }
+}
diff --git a/src/test/ui/match/issue-46920-byte-array-patterns.rs b/src/test/ui/match/issue-46920-byte-array-patterns.rs
new file mode 100644
index 000000000..2a8b4bb49
--- /dev/null
+++ b/src/test/ui/match/issue-46920-byte-array-patterns.rs
@@ -0,0 +1,28 @@
+// run-pass
+const CURSOR_PARTITION_LABEL: &'static [u8] = b"partition";
+const CURSOR_EVENT_TYPE_LABEL: &'static [u8] = b"event_type";
+const BYTE_PATTERN: &'static [u8; 5] = b"hello";
+
+fn match_slice(x: &[u8]) -> u32 {
+ match x {
+ CURSOR_PARTITION_LABEL => 0,
+ CURSOR_EVENT_TYPE_LABEL => 1,
+ _ => 2,
+ }
+}
+
+fn match_array(x: &[u8; 5]) -> bool {
+ match x {
+ BYTE_PATTERN => true,
+ _ => false
+ }
+}
+
+fn main() {
+ assert_eq!(match_slice(b"abcde"), 2);
+ assert_eq!(match_slice(b"event_type"), 1);
+ assert_eq!(match_slice(b"partition"), 0);
+
+ assert_eq!(match_array(b"hello"), true);
+ assert_eq!(match_array(b"hella"), false);
+}
diff --git a/src/test/ui/match/issue-56685.rs b/src/test/ui/match/issue-56685.rs
new file mode 100644
index 000000000..f320c99ed
--- /dev/null
+++ b/src/test/ui/match/issue-56685.rs
@@ -0,0 +1,44 @@
+#![allow(dead_code)]
+#![deny(unused_variables)]
+
+// This test aims to check that unused variable suggestions update bindings in all
+// match arms.
+
+fn main() {
+ enum E {
+ A(i32,),
+ B(i32,),
+ }
+
+ match E::A(1) {
+ E::A(x) | E::B(x) => {}
+ //~^ ERROR unused variable: `x`
+ }
+
+ enum F {
+ A(i32, i32,),
+ B(i32, i32,),
+ C(i32, i32,),
+ }
+
+ let _ = match F::A(1, 2) {
+ F::A(x, y) | F::B(x, y) => { y },
+ //~^ ERROR unused variable: `x`
+ F::C(a, b) => { 3 }
+ //~^ ERROR unused variable: `a`
+ //~^^ ERROR unused variable: `b`
+ };
+
+ let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
+ //~^ ERROR unused variable: `x`
+ y
+ } else {
+ 3
+ };
+
+ while let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
+ //~^ ERROR unused variable: `x`
+ let _ = y;
+ break;
+ }
+}
diff --git a/src/test/ui/match/issue-56685.stderr b/src/test/ui/match/issue-56685.stderr
new file mode 100644
index 000000000..ccf357d4a
--- /dev/null
+++ b/src/test/ui/match/issue-56685.stderr
@@ -0,0 +1,63 @@
+error: unused variable: `x`
+ --> $DIR/issue-56685.rs:14:14
+ |
+LL | E::A(x) | E::B(x) => {}
+ | ^ ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-56685.rs:2:9
+ |
+LL | #![deny(unused_variables)]
+ | ^^^^^^^^^^^^^^^^
+help: if this is intentional, prefix it with an underscore
+ |
+LL | E::A(_x) | E::B(_x) => {}
+ | ~~ ~~
+
+error: unused variable: `x`
+ --> $DIR/issue-56685.rs:25:14
+ |
+LL | F::A(x, y) | F::B(x, y) => { y },
+ | ^ ^
+ |
+help: if this is intentional, prefix it with an underscore
+ |
+LL | F::A(_x, y) | F::B(_x, y) => { y },
+ | ~~ ~~
+
+error: unused variable: `a`
+ --> $DIR/issue-56685.rs:27:14
+ |
+LL | F::C(a, b) => { 3 }
+ | ^ help: if this is intentional, prefix it with an underscore: `_a`
+
+error: unused variable: `b`
+ --> $DIR/issue-56685.rs:27:17
+ |
+LL | F::C(a, b) => { 3 }
+ | ^ help: if this is intentional, prefix it with an underscore: `_b`
+
+error: unused variable: `x`
+ --> $DIR/issue-56685.rs:32:25
+ |
+LL | let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
+ | ^ ^
+ |
+help: if this is intentional, prefix it with an underscore
+ |
+LL | let _ = if let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) {
+ | ~~ ~~
+
+error: unused variable: `x`
+ --> $DIR/issue-56685.rs:39:20
+ |
+LL | while let F::A(x, y) | F::B(x, y) = F::A(1, 2) {
+ | ^ ^
+ |
+help: if this is intentional, prefix it with an underscore
+ |
+LL | while let F::A(_x, y) | F::B(_x, y) = F::A(1, 2) {
+ | ~~ ~~
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/match/issue-70972-dyn-trait.rs b/src/test/ui/match/issue-70972-dyn-trait.rs
new file mode 100644
index 000000000..97d161c59
--- /dev/null
+++ b/src/test/ui/match/issue-70972-dyn-trait.rs
@@ -0,0 +1,10 @@
+const F: &'static dyn Send = &7u32;
+
+fn main() {
+ let a: &dyn Send = &7u32;
+ match a {
+ F => panic!(),
+ //~^ ERROR `&dyn Send` cannot be used in patterns
+ _ => {}
+ }
+}
diff --git a/src/test/ui/match/issue-70972-dyn-trait.stderr b/src/test/ui/match/issue-70972-dyn-trait.stderr
new file mode 100644
index 000000000..7581070eb
--- /dev/null
+++ b/src/test/ui/match/issue-70972-dyn-trait.stderr
@@ -0,0 +1,8 @@
+error: `&dyn Send` cannot be used in patterns
+ --> $DIR/issue-70972-dyn-trait.rs:6:9
+ |
+LL | F => panic!(),
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/match/issue-72680.rs b/src/test/ui/match/issue-72680.rs
new file mode 100644
index 000000000..c13cace76
--- /dev/null
+++ b/src/test/ui/match/issue-72680.rs
@@ -0,0 +1,63 @@
+// run-pass
+
+fn main() {
+ assert!(f("", 0));
+ assert!(f("a", 1));
+ assert!(f("b", 1));
+
+ assert!(!f("", 1));
+ assert!(!f("a", 0));
+ assert!(!f("b", 0));
+
+ assert!(!f("asdf", 32));
+
+ ////
+
+ assert!(!g(true, true, true));
+ assert!(!g(false, true, true));
+ assert!(!g(true, false, true));
+ assert!(!g(false, false, true));
+ assert!(!g(true, true, false));
+
+ assert!(g(false, true, false));
+ assert!(g(true, false, false));
+ assert!(g(false, false, false));
+
+ ////
+
+ assert!(!h(true, true, true));
+ assert!(!h(false, true, true));
+ assert!(!h(true, false, true));
+ assert!(!h(false, false, true));
+ assert!(!h(true, true, false));
+
+ assert!(h(false, true, false));
+ assert!(h(true, false, false));
+ assert!(h(false, false, false));
+}
+
+fn f(s: &str, num: usize) -> bool {
+ match (s, num) {
+ ("", 0) | ("a" | "b", 1) => true,
+
+ _ => false,
+ }
+}
+
+fn g(x: bool, y: bool, z: bool) -> bool {
+ match (x, y, x, z) {
+ (true | false, false, true, false) => true,
+ (false, true | false, true | false, false) => true,
+ (true | false, true | false, true | false, true) => false,
+ (true, true | false, true | false, false) => false,
+ }
+}
+
+fn h(x: bool, y: bool, z: bool) -> bool {
+ match (x, (y, (x, (z,)))) {
+ (true | false, (false, (true, (false,)))) => true,
+ (false, (true | false, (true | false, (false,)))) => true,
+ (true | false, (true | false, (true | false, (true,)))) => false,
+ (true, (true | false, (true | false, (false,)))) => false,
+ }
+}
diff --git a/src/test/ui/match/issue-72896.rs b/src/test/ui/match/issue-72896.rs
new file mode 100644
index 000000000..3a8b82037
--- /dev/null
+++ b/src/test/ui/match/issue-72896.rs
@@ -0,0 +1,23 @@
+// run-pass
+trait EnumSetType {
+ type Repr;
+}
+
+enum Enum8 { }
+impl EnumSetType for Enum8 {
+ type Repr = u8;
+}
+
+#[derive(PartialEq, Eq)]
+struct EnumSet<T: EnumSetType> {
+ __enumset_underlying: T::Repr,
+}
+
+const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
+
+fn main() {
+ match CONST_SET {
+ CONST_SET => { /* ok */ }
+ _ => panic!("match fell through?"),
+ }
+}
diff --git a/src/test/ui/match/issue-74050-end-span.rs b/src/test/ui/match/issue-74050-end-span.rs
new file mode 100644
index 000000000..cc81214e2
--- /dev/null
+++ b/src/test/ui/match/issue-74050-end-span.rs
@@ -0,0 +1,13 @@
+fn main() {
+ let mut args = std::env::args_os();
+ let _arg = match args.next() {
+ Some(arg) => {
+ match arg.to_str() {
+ //~^ ERROR `arg` does not live long enough
+ Some(s) => s,
+ None => return,
+ }
+ }
+ None => return,
+ };
+}
diff --git a/src/test/ui/match/issue-74050-end-span.stderr b/src/test/ui/match/issue-74050-end-span.stderr
new file mode 100644
index 000000000..59c091e44
--- /dev/null
+++ b/src/test/ui/match/issue-74050-end-span.stderr
@@ -0,0 +1,15 @@
+error[E0597]: `arg` does not live long enough
+ --> $DIR/issue-74050-end-span.rs:5:19
+ |
+LL | let _arg = match args.next() {
+ | ---- borrow later stored here
+LL | Some(arg) => {
+LL | match arg.to_str() {
+ | ^^^^^^^^^^^^ borrowed value does not live long enough
+...
+LL | }
+ | - `arg` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/match/issue-82392.rs b/src/test/ui/match/issue-82392.rs
new file mode 100644
index 000000000..d26d88304
--- /dev/null
+++ b/src/test/ui/match/issue-82392.rs
@@ -0,0 +1,9 @@
+// https://github.com/rust-lang/rust/issues/82329
+// compile-flags: -Zunpretty=hir,typed
+// check-pass
+
+pub fn main() {
+ if true {
+ } else if let Some(a) = Some(3) {
+ }
+}
diff --git a/src/test/ui/match/issue-82392.stdout b/src/test/ui/match/issue-82392.stdout
new file mode 100644
index 000000000..ffe730743
--- /dev/null
+++ b/src/test/ui/match/issue-82392.stdout
@@ -0,0 +1,16 @@
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+// https://github.com/rust-lang/rust/issues/82329
+// compile-flags: -Zunpretty=hir,typed
+// check-pass
+
+fn main() ({
+ (if (true as bool)
+ ({ } as
+ ()) else if (let Some(a) =
+ ((Some as
+ fn(i32) -> Option<i32> {Option::<i32>::Some})((3 as i32)) as
+ Option<i32>) as bool) ({ } as ()) as ())
+ } as ())
diff --git a/src/test/ui/match/issue-82866.rs b/src/test/ui/match/issue-82866.rs
new file mode 100644
index 000000000..95cd62261
--- /dev/null
+++ b/src/test/ui/match/issue-82866.rs
@@ -0,0 +1,7 @@
+fn main() {
+ match x {
+ //~^ ERROR cannot find value `x` in this scope
+ Some::<v>(v) => (),
+ //~^ ERROR cannot find type `v` in this scope
+ }
+}
diff --git a/src/test/ui/match/issue-82866.stderr b/src/test/ui/match/issue-82866.stderr
new file mode 100644
index 000000000..f9e3360a5
--- /dev/null
+++ b/src/test/ui/match/issue-82866.stderr
@@ -0,0 +1,16 @@
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/issue-82866.rs:2:11
+ |
+LL | match x {
+ | ^ not found in this scope
+
+error[E0412]: cannot find type `v` in this scope
+ --> $DIR/issue-82866.rs:4:16
+ |
+LL | Some::<v>(v) => (),
+ | ^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0412, E0425.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/match/issue-84434.rs b/src/test/ui/match/issue-84434.rs
new file mode 100644
index 000000000..423481fd5
--- /dev/null
+++ b/src/test/ui/match/issue-84434.rs
@@ -0,0 +1,18 @@
+// https://github.com/rust-lang/rust/issues/84434
+// check-pass
+
+use std::path::Path;
+struct A {
+ pub func: fn(check: bool, a: &Path, b: Option<&Path>),
+}
+const MY_A: A = A {
+ func: |check, a, b| {
+ if check {
+ let _ = ();
+ } else if let Some(parent) = b.and_then(|p| p.parent()) {
+ let _ = ();
+ }
+ },
+};
+
+fn main() {}
diff --git a/src/test/ui/match/issue-91058.rs b/src/test/ui/match/issue-91058.rs
new file mode 100644
index 000000000..4845937d5
--- /dev/null
+++ b/src/test/ui/match/issue-91058.rs
@@ -0,0 +1,11 @@
+struct S(());
+
+fn main() {
+ let array = [S(())];
+
+ match array {
+ [()] => {}
+ //~^ ERROR mismatched types [E0308]
+ _ => {}
+ }
+}
diff --git a/src/test/ui/match/issue-91058.stderr b/src/test/ui/match/issue-91058.stderr
new file mode 100644
index 000000000..ec1d7e21f
--- /dev/null
+++ b/src/test/ui/match/issue-91058.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-91058.rs:7:10
+ |
+LL | match array {
+ | ----- this expression has type `[S; 1]`
+LL | [()] => {}
+ | ^^ expected struct `S`, found `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/match/issue-92100.rs b/src/test/ui/match/issue-92100.rs
new file mode 100644
index 000000000..021166b2b
--- /dev/null
+++ b/src/test/ui/match/issue-92100.rs
@@ -0,0 +1,7 @@
+#![feature(half_open_range_patterns)]
+
+fn main() {
+ match [1, 2] {
+ [a.., a] => {} //~ ERROR cannot find value `a` in this scope
+ }
+}
diff --git a/src/test/ui/match/issue-92100.stderr b/src/test/ui/match/issue-92100.stderr
new file mode 100644
index 000000000..0f694c587
--- /dev/null
+++ b/src/test/ui/match/issue-92100.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `a` in this scope
+ --> $DIR/issue-92100.rs:5:10
+ |
+LL | [a.., a] => {}
+ | ^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/match/match-arm-resolving-to-never.rs b/src/test/ui/match/match-arm-resolving-to-never.rs
new file mode 100644
index 000000000..6ef249c05
--- /dev/null
+++ b/src/test/ui/match/match-arm-resolving-to-never.rs
@@ -0,0 +1,19 @@
+enum E {
+ A,
+ B,
+ C,
+ D,
+ E,
+ F,
+}
+
+fn main() {
+ match E::F {
+ E::A => 1,
+ E::B => 2,
+ E::C => 3,
+ E::D => 4,
+ E::E => unimplemented!(""),
+ E::F => "", //~ ERROR `match` arms have incompatible types
+ };
+}
diff --git a/src/test/ui/match/match-arm-resolving-to-never.stderr b/src/test/ui/match/match-arm-resolving-to-never.stderr
new file mode 100644
index 000000000..686fbd0ba
--- /dev/null
+++ b/src/test/ui/match/match-arm-resolving-to-never.stderr
@@ -0,0 +1,18 @@
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/match-arm-resolving-to-never.rs:17:17
+ |
+LL | / match E::F {
+LL | | E::A => 1,
+LL | | E::B => 2,
+LL | | E::C => 3,
+LL | | E::D => 4,
+LL | | E::E => unimplemented!(""),
+ | | ------------------ this and all prior arms are found to be of type `{integer}`
+LL | | E::F => "",
+ | | ^^ expected integer, found `&str`
+LL | | };
+ | |_____- `match` arms have incompatible types
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/match/match-bot-panic.rs b/src/test/ui/match/match-bot-panic.rs
new file mode 100644
index 000000000..e4a6f6d6f
--- /dev/null
+++ b/src/test/ui/match/match-bot-panic.rs
@@ -0,0 +1,16 @@
+// run-fail
+// error-pattern:explicit panic
+// ignore-emscripten no processes
+
+#![allow(unreachable_code)]
+#![allow(unused_variables)]
+
+fn foo(s: String) {}
+
+fn main() {
+ let i = match Some::<isize>(3) {
+ None::<isize> => panic!(),
+ Some::<isize>(_) => panic!(),
+ };
+ foo(i);
+}
diff --git a/src/test/ui/match/match-disc-bot.rs b/src/test/ui/match/match-disc-bot.rs
new file mode 100644
index 000000000..18cfd5e23
--- /dev/null
+++ b/src/test/ui/match/match-disc-bot.rs
@@ -0,0 +1,16 @@
+// run-fail
+// error-pattern:quux
+// ignore-emscripten no processes
+
+fn f() -> ! {
+ panic!("quux")
+}
+fn g() -> isize {
+ match f() {
+ true => 1,
+ false => 0,
+ }
+}
+fn main() {
+ g();
+}
diff --git a/src/test/ui/match/match-fn-call.rs b/src/test/ui/match/match-fn-call.rs
new file mode 100644
index 000000000..99092602c
--- /dev/null
+++ b/src/test/ui/match/match-fn-call.rs
@@ -0,0 +1,12 @@
+use std::path::Path;
+
+fn main() {
+ let path = Path::new("foo");
+ match path {
+ Path::new("foo") => println!("foo"),
+ //~^ ERROR expected tuple struct or tuple variant
+ Path::new("bar") => println!("bar"),
+ //~^ ERROR expected tuple struct or tuple variant
+ _ => (),
+ }
+}
diff --git a/src/test/ui/match/match-fn-call.stderr b/src/test/ui/match/match-fn-call.stderr
new file mode 100644
index 000000000..297aa4cd9
--- /dev/null
+++ b/src/test/ui/match/match-fn-call.stderr
@@ -0,0 +1,19 @@
+error[E0164]: expected tuple struct or tuple variant, found associated function `Path::new`
+ --> $DIR/match-fn-call.rs:6:9
+ |
+LL | Path::new("foo") => println!("foo"),
+ | ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
+ |
+ = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+
+error[E0164]: expected tuple struct or tuple variant, found associated function `Path::new`
+ --> $DIR/match-fn-call.rs:8:9
+ |
+LL | Path::new("bar") => println!("bar"),
+ | ^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
+ |
+ = help: for more information, visit https://doc.rust-lang.org/book/ch18-00-patterns.html
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0164`.
diff --git a/src/test/ui/match/match-ill-type2.rs b/src/test/ui/match/match-ill-type2.rs
new file mode 100644
index 000000000..6612f6e39
--- /dev/null
+++ b/src/test/ui/match/match-ill-type2.rs
@@ -0,0 +1,7 @@
+fn main() {
+ match 1i32 {
+ 1i32 => 1,
+ 2u32 => 1, //~ ERROR mismatched types
+ _ => 2,
+ };
+}
diff --git a/src/test/ui/match/match-ill-type2.stderr b/src/test/ui/match/match-ill-type2.stderr
new file mode 100644
index 000000000..5078f03d6
--- /dev/null
+++ b/src/test/ui/match/match-ill-type2.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/match-ill-type2.rs:4:9
+ |
+LL | match 1i32 {
+ | ---- this expression has type `i32`
+LL | 1i32 => 1,
+LL | 2u32 => 1,
+ | ^^^^ expected `i32`, found `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/match/match-incompat-type-semi.rs b/src/test/ui/match/match-incompat-type-semi.rs
new file mode 100644
index 000000000..37f6beabd
--- /dev/null
+++ b/src/test/ui/match/match-incompat-type-semi.rs
@@ -0,0 +1,52 @@
+// Diagnostic enhancement explained in issue #75418.
+// Point at the last statement in the block if there's no tail expression,
+// and suggest removing the semicolon if appropriate.
+
+fn main() {
+ let _ = match Some(42) {
+ Some(x) => {
+ x
+ },
+ None => {
+ 0;
+ //~^ ERROR incompatible types
+ //~| HELP consider removing this semicolon
+ },
+ };
+
+ let _ = if let Some(x) = Some(42) {
+ x
+ } else {
+ 0;
+ //~^ ERROR incompatible types
+ //~| HELP consider removing this semicolon
+ };
+
+ let _ = match Some(42) {
+ Some(x) => {
+ x
+ },
+ None => {
+ ();
+ //~^ ERROR incompatible types
+ },
+ };
+
+ let _ = match Some(42) {
+ Some(x) => {
+ x
+ },
+ None => { //~ ERROR incompatible types
+ },
+ };
+
+ let _ = match Some(42) {
+ Some(x) => "rust-lang.org"
+ .chars()
+ .skip(1)
+ .chain(Some(x as u8 as char))
+ .take(10)
+ .any(char::is_alphanumeric),
+ None => {} //~ ERROR incompatible types
+ };
+}
diff --git a/src/test/ui/match/match-incompat-type-semi.stderr b/src/test/ui/match/match-incompat-type-semi.stderr
new file mode 100644
index 000000000..008b1c1e9
--- /dev/null
+++ b/src/test/ui/match/match-incompat-type-semi.stderr
@@ -0,0 +1,88 @@
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/match-incompat-type-semi.rs:11:13
+ |
+LL | let _ = match Some(42) {
+ | _____________-
+LL | | Some(x) => {
+LL | | x
+ | | - this is found to be of type `{integer}`
+LL | | },
+LL | | None => {
+LL | | 0;
+ | | ^-
+ | | ||
+ | | |help: consider removing this semicolon
+ | | expected integer, found `()`
+... |
+LL | | },
+LL | | };
+ | |_____- `match` arms have incompatible types
+
+error[E0308]: `if` and `else` have incompatible types
+ --> $DIR/match-incompat-type-semi.rs:20:9
+ |
+LL | let _ = if let Some(x) = Some(42) {
+ | _____________-
+LL | | x
+ | | - expected because of this
+LL | | } else {
+LL | | 0;
+ | | ^-
+ | | ||
+ | | |help: consider removing this semicolon
+ | | expected integer, found `()`
+LL | |
+LL | |
+LL | | };
+ | |_____- `if` and `else` have incompatible types
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/match-incompat-type-semi.rs:30:13
+ |
+LL | let _ = match Some(42) {
+ | _____________-
+LL | | Some(x) => {
+LL | | x
+ | | - this is found to be of type `{integer}`
+LL | | },
+LL | | None => {
+LL | | ();
+ | | ^^^ expected integer, found `()`
+LL | |
+LL | | },
+LL | | };
+ | |_____- `match` arms have incompatible types
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/match-incompat-type-semi.rs:39:17
+ |
+LL | let _ = match Some(42) {
+ | -------------- `match` arms have incompatible types
+LL | Some(x) => {
+LL | x
+ | - this is found to be of type `{integer}`
+LL | },
+LL | None => {
+ | _________________^
+LL | | },
+ | |_________^ expected integer, found `()`
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/match-incompat-type-semi.rs:50:17
+ |
+LL | let _ = match Some(42) {
+ | -------------- `match` arms have incompatible types
+LL | Some(x) => "rust-lang.org"
+ | ____________________-
+LL | | .chars()
+LL | | .skip(1)
+LL | | .chain(Some(x as u8 as char))
+LL | | .take(10)
+LL | | .any(char::is_alphanumeric),
+ | |_______________________________________- this is found to be of type `bool`
+LL | None => {}
+ | ^^ expected `bool`, found `()`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/match/match-join.rs b/src/test/ui/match/match-join.rs
new file mode 100644
index 000000000..b0f2593c8
--- /dev/null
+++ b/src/test/ui/match/match-join.rs
@@ -0,0 +1,11 @@
+// a good test that we merge paths correctly in the presence of a
+// variable that's used before it's declared
+
+fn my_panic() -> ! { panic!(); }
+
+fn main() {
+ match true { false => { my_panic(); } true => { } }
+
+ println!("{}", x); //~ ERROR cannot find value `x` in this scope
+ let x: isize;
+}
diff --git a/src/test/ui/match/match-join.stderr b/src/test/ui/match/match-join.stderr
new file mode 100644
index 000000000..27a82c124
--- /dev/null
+++ b/src/test/ui/match/match-join.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `x` in this scope
+ --> $DIR/match-join.rs:9:20
+ |
+LL | println!("{}", x);
+ | ^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/match/match-no-arms-unreachable-after.rs b/src/test/ui/match/match-no-arms-unreachable-after.rs
new file mode 100644
index 000000000..8f83fd1a3
--- /dev/null
+++ b/src/test/ui/match/match-no-arms-unreachable-after.rs
@@ -0,0 +1,12 @@
+#![allow(warnings)]
+#![deny(unreachable_code)]
+
+enum Void { }
+
+fn foo(v: Void) {
+ match v { }
+ let x = 2; //~ ERROR unreachable
+}
+
+fn main() {
+}
diff --git a/src/test/ui/match/match-no-arms-unreachable-after.stderr b/src/test/ui/match/match-no-arms-unreachable-after.stderr
new file mode 100644
index 000000000..a0a369726
--- /dev/null
+++ b/src/test/ui/match/match-no-arms-unreachable-after.stderr
@@ -0,0 +1,16 @@
+error: unreachable statement
+ --> $DIR/match-no-arms-unreachable-after.rs:8:5
+ |
+LL | match v { }
+ | ----------- any code following this expression is unreachable
+LL | let x = 2;
+ | ^^^^^^^^^^ unreachable statement
+ |
+note: the lint level is defined here
+ --> $DIR/match-no-arms-unreachable-after.rs:2:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/match/match-on-negative-integer-ranges.rs b/src/test/ui/match/match-on-negative-integer-ranges.rs
new file mode 100644
index 000000000..53e9ea9a5
--- /dev/null
+++ b/src/test/ui/match/match-on-negative-integer-ranges.rs
@@ -0,0 +1,7 @@
+// run-pass
+
+fn main() {
+ assert_eq!(false, match -50_i8 { -128i8..=-101i8 => true, _ => false, });
+
+ assert_eq!(false, if let -128i8..=-101i8 = -50_i8 { true } else { false });
+}
diff --git a/src/test/ui/match/match-pattern-field-mismatch-2.rs b/src/test/ui/match/match-pattern-field-mismatch-2.rs
new file mode 100644
index 000000000..fa03cdac2
--- /dev/null
+++ b/src/test/ui/match/match-pattern-field-mismatch-2.rs
@@ -0,0 +1,16 @@
+fn main() {
+ enum Color {
+ Rgb(usize, usize, usize),
+ Cmyk(usize, usize, usize, usize),
+ NoColor,
+ }
+
+ fn foo(c: Color) {
+ match c {
+ Color::Rgb(_, _, _) => { }
+ Color::Cmyk(_, _, _, _) => { }
+ Color::NoColor(_) => { }
+ //~^ ERROR expected tuple struct or tuple variant, found unit variant `Color::NoColor`
+ }
+ }
+}
diff --git a/src/test/ui/match/match-pattern-field-mismatch-2.stderr b/src/test/ui/match/match-pattern-field-mismatch-2.stderr
new file mode 100644
index 000000000..ba32d0e99
--- /dev/null
+++ b/src/test/ui/match/match-pattern-field-mismatch-2.stderr
@@ -0,0 +1,12 @@
+error[E0532]: expected tuple struct or tuple variant, found unit variant `Color::NoColor`
+ --> $DIR/match-pattern-field-mismatch-2.rs:12:11
+ |
+LL | NoColor,
+ | ------- `Color::NoColor` defined here
+...
+LL | Color::NoColor(_) => { }
+ | ^^^^^^^^^^^^^^^^^ help: use this syntax instead: `Color::NoColor`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0532`.
diff --git a/src/test/ui/match/match-pattern-field-mismatch.rs b/src/test/ui/match/match-pattern-field-mismatch.rs
new file mode 100644
index 000000000..a4fa97fef
--- /dev/null
+++ b/src/test/ui/match/match-pattern-field-mismatch.rs
@@ -0,0 +1,16 @@
+fn main() {
+ enum Color {
+ Rgb(usize, usize, usize),
+ Cmyk(usize, usize, usize, usize),
+ NoColor,
+ }
+
+ fn foo(c: Color) {
+ match c {
+ Color::Rgb(_, _) => { }
+ //~^ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3
+ Color::Cmyk(_, _, _, _) => { }
+ Color::NoColor => { }
+ }
+ }
+}
diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr
new file mode 100644
index 000000000..c994ee4f6
--- /dev/null
+++ b/src/test/ui/match/match-pattern-field-mismatch.stderr
@@ -0,0 +1,21 @@
+error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields
+ --> $DIR/match-pattern-field-mismatch.rs:10:22
+ |
+LL | Rgb(usize, usize, usize),
+ | ----- ----- ----- tuple variant has 3 fields
+...
+LL | Color::Rgb(_, _) => { }
+ | ^ ^ expected 3 fields, found 2
+ |
+help: use `_` to explicitly ignore each field
+ |
+LL | Color::Rgb(_, _, _) => { }
+ | +++
+help: use `..` to ignore all fields
+ |
+LL | Color::Rgb(..) => { }
+ | ~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0023`.
diff --git a/src/test/ui/match/match-range-fail-2.rs b/src/test/ui/match/match-range-fail-2.rs
new file mode 100644
index 000000000..792664e1d
--- /dev/null
+++ b/src/test/ui/match/match-range-fail-2.rs
@@ -0,0 +1,24 @@
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ match 5 {
+ 6 ..= 1 => { }
+ _ => { }
+ };
+ //~^^^ ERROR lower range bound must be less than or equal to upper
+ //~| ERROR lower range bound must be less than or equal to upper
+
+ match 5 {
+ 0 .. 0 => { }
+ _ => { }
+ };
+ //~^^^ ERROR lower range bound must be less than upper
+ //~| ERROR lower range bound must be less than upper
+
+ match 5u64 {
+ 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { }
+ _ => { }
+ };
+ //~^^^ ERROR lower range bound must be less than or equal to upper
+ //~| ERROR lower range bound must be less than or equal to upper
+}
diff --git a/src/test/ui/match/match-range-fail-2.stderr b/src/test/ui/match/match-range-fail-2.stderr
new file mode 100644
index 000000000..7a0852d7e
--- /dev/null
+++ b/src/test/ui/match/match-range-fail-2.stderr
@@ -0,0 +1,40 @@
+error[E0030]: lower range bound must be less than or equal to upper
+ --> $DIR/match-range-fail-2.rs:5:9
+ |
+LL | 6 ..= 1 => { }
+ | ^ lower bound larger than upper bound
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/match-range-fail-2.rs:12:9
+ |
+LL | 0 .. 0 => { }
+ | ^
+
+error[E0030]: lower range bound must be less than or equal to upper
+ --> $DIR/match-range-fail-2.rs:19:9
+ |
+LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { }
+ | ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound
+
+error[E0030]: lower range bound must be less than or equal to upper
+ --> $DIR/match-range-fail-2.rs:5:9
+ |
+LL | 6 ..= 1 => { }
+ | ^ lower bound larger than upper bound
+
+error[E0579]: lower range bound must be less than upper
+ --> $DIR/match-range-fail-2.rs:12:9
+ |
+LL | 0 .. 0 => { }
+ | ^
+
+error[E0030]: lower range bound must be less than or equal to upper
+ --> $DIR/match-range-fail-2.rs:19:9
+ |
+LL | 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { }
+ | ^^^^^^^^^^^^^^^^^^^^^ lower bound larger than upper bound
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0030, E0579.
+For more information about an error, try `rustc --explain E0030`.
diff --git a/src/test/ui/match/match-range-fail.rs b/src/test/ui/match/match-range-fail.rs
new file mode 100644
index 000000000..e53c8463e
--- /dev/null
+++ b/src/test/ui/match/match-range-fail.rs
@@ -0,0 +1,22 @@
+fn main() {
+ match "wow" {
+ "bar" ..= "foo" => { }
+ };
+ //~^^ ERROR only `char` and numeric types are allowed in range
+
+ match "wow" {
+ 10 ..= "what" => ()
+ };
+ //~^^ ERROR only `char` and numeric types are allowed in range
+
+ match "wow" {
+ true ..= "what" => {}
+ };
+ //~^^ ERROR only `char` and numeric types are allowed in range
+
+ match 5 {
+ 'c' ..= 100 => { }
+ _ => { }
+ };
+ //~^^^ ERROR mismatched types
+}
diff --git a/src/test/ui/match/match-range-fail.stderr b/src/test/ui/match/match-range-fail.stderr
new file mode 100644
index 000000000..65db92df1
--- /dev/null
+++ b/src/test/ui/match/match-range-fail.stderr
@@ -0,0 +1,40 @@
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/match-range-fail.rs:3:9
+ |
+LL | "bar" ..= "foo" => { }
+ | -----^^^^^-----
+ | | |
+ | | this is of type `&'static str` but it should be `char` or numeric
+ | this is of type `&'static str` but it should be `char` or numeric
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/match-range-fail.rs:8:16
+ |
+LL | 10 ..= "what" => ()
+ | -- ^^^^^^ this is of type `&'static str` but it should be `char` or numeric
+ | |
+ | this is of type `{integer}`
+
+error[E0029]: only `char` and numeric types are allowed in range patterns
+ --> $DIR/match-range-fail.rs:13:9
+ |
+LL | true ..= "what" => {}
+ | ----^^^^^------
+ | | |
+ | | this is of type `&'static str` but it should be `char` or numeric
+ | this is of type `bool` but it should be `char` or numeric
+
+error[E0308]: mismatched types
+ --> $DIR/match-range-fail.rs:18:9
+ |
+LL | match 5 {
+ | - this expression has type `{integer}`
+LL | 'c' ..= 100 => { }
+ | ^^^ --- this is of type `{integer}`
+ | |
+ | expected integer, found `char`
+
+error: aborting due to 4 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/match/match-ref-mut-invariance.rs b/src/test/ui/match/match-ref-mut-invariance.rs
new file mode 100644
index 000000000..4250696c6
--- /dev/null
+++ b/src/test/ui/match/match-ref-mut-invariance.rs
@@ -0,0 +1,15 @@
+// Check that when making a ref mut binding with type `&mut T`, the
+// type `T` must match precisely the type `U` of the value being
+// matched, and in particular cannot be some supertype of `U`. Issue
+// #23116. This test focuses on a `match`.
+
+#![allow(dead_code)]
+struct S<'b>(&'b i32);
+impl<'b> S<'b> {
+ fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
+ match self.0 { ref mut x => x }
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/match/match-ref-mut-invariance.stderr b/src/test/ui/match/match-ref-mut-invariance.stderr
new file mode 100644
index 000000000..3b7e53cd5
--- /dev/null
+++ b/src/test/ui/match/match-ref-mut-invariance.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+ --> $DIR/match-ref-mut-invariance.rs:10:9
+ |
+LL | impl<'b> S<'b> {
+ | -- lifetime `'b` defined here
+LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
+ | -- lifetime `'a` defined here
+LL | match self.0 { ref mut x => x }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+ = note: requirement occurs because of a mutable reference to `&i32`
+ = note: mutable references are invariant over their type parameter
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/match/match-ref-mut-let-invariance.rs b/src/test/ui/match/match-ref-mut-let-invariance.rs
new file mode 100644
index 000000000..a33be09ac
--- /dev/null
+++ b/src/test/ui/match/match-ref-mut-let-invariance.rs
@@ -0,0 +1,16 @@
+// Check that when making a ref mut binding with type `&mut T`, the
+// type `T` must match precisely the type `U` of the value being
+// matched, and in particular cannot be some supertype of `U`. Issue
+// #23116. This test focuses on a `let`.
+
+#![allow(dead_code)]
+struct S<'b>(&'b i32);
+impl<'b> S<'b> {
+ fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
+ let ref mut x = self.0;
+ x
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/match/match-ref-mut-let-invariance.stderr b/src/test/ui/match/match-ref-mut-let-invariance.stderr
new file mode 100644
index 000000000..f4d1cea67
--- /dev/null
+++ b/src/test/ui/match/match-ref-mut-let-invariance.stderr
@@ -0,0 +1,18 @@
+error: lifetime may not live long enough
+ --> $DIR/match-ref-mut-let-invariance.rs:11:9
+ |
+LL | impl<'b> S<'b> {
+ | -- lifetime `'b` defined here
+LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
+ | -- lifetime `'a` defined here
+LL | let ref mut x = self.0;
+LL | x
+ | ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+ = note: requirement occurs because of a mutable reference to `&i32`
+ = note: mutable references are invariant over their type parameter
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/match/match-ref-mut-stability.rs b/src/test/ui/match/match-ref-mut-stability.rs
new file mode 100644
index 000000000..52120360b
--- /dev/null
+++ b/src/test/ui/match/match-ref-mut-stability.rs
@@ -0,0 +1,37 @@
+// Check that `ref mut` variables don't change address between the match guard
+// and the arm expression.
+
+// run-pass
+
+// Test that z always point to the same temporary.
+fn referent_stability() {
+ let p;
+ match 0 {
+ ref mut z if { p = z as *const _; true } => assert_eq!(p, z as *const _),
+ _ => unreachable!(),
+ };
+}
+
+// Test that z is always effectively the same variable.
+fn variable_stability() {
+ let p;
+ match 0 {
+ ref mut z if { p = &z as *const _; true } => assert_eq!(p, &z as *const _),
+ _ => unreachable!(),
+ };
+}
+
+// Test that a borrow of *z can cross from the guard to the arm.
+fn persist_borrow() {
+ let r;
+ match 0 {
+ ref mut z if { r = z as &_; true } => assert_eq!(*r, 0),
+ _ => unreachable!(),
+ }
+}
+
+fn main() {
+ referent_stability();
+ variable_stability();
+ persist_borrow();
+}
diff --git a/src/test/ui/match/match-struct.rs b/src/test/ui/match/match-struct.rs
new file mode 100644
index 000000000..7a54c54b9
--- /dev/null
+++ b/src/test/ui/match/match-struct.rs
@@ -0,0 +1,11 @@
+struct S { a: isize }
+enum E { C(isize) }
+
+fn main() {
+ match (S { a: 1 }) {
+ E::C(_) => (),
+ //~^ ERROR mismatched types
+ //~| expected struct `S`, found enum `E`
+ _ => ()
+ }
+}
diff --git a/src/test/ui/match/match-struct.stderr b/src/test/ui/match/match-struct.stderr
new file mode 100644
index 000000000..a475bd5e5
--- /dev/null
+++ b/src/test/ui/match/match-struct.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> $DIR/match-struct.rs:6:9
+ |
+LL | match (S { a: 1 }) {
+ | ------------ this expression has type `S`
+LL | E::C(_) => (),
+ | ^^^^^^^ expected struct `S`, found enum `E`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/match/match-tag-nullary.rs b/src/test/ui/match/match-tag-nullary.rs
new file mode 100644
index 000000000..bb2f59969
--- /dev/null
+++ b/src/test/ui/match/match-tag-nullary.rs
@@ -0,0 +1,4 @@
+enum A { A }
+enum B { B }
+
+fn main() { let x: A = A::A; match x { B::B => { } } } //~ ERROR mismatched types
diff --git a/src/test/ui/match/match-tag-nullary.stderr b/src/test/ui/match/match-tag-nullary.stderr
new file mode 100644
index 000000000..a6add31d1
--- /dev/null
+++ b/src/test/ui/match/match-tag-nullary.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/match-tag-nullary.rs:4:40
+ |
+LL | enum B { B }
+ | - unit variant defined here
+LL |
+LL | fn main() { let x: A = A::A; match x { B::B => { } } }
+ | - ^^^^ expected enum `A`, found enum `B`
+ | |
+ | this expression has type `A`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/match/match-tag-unary.rs b/src/test/ui/match/match-tag-unary.rs
new file mode 100644
index 000000000..aedceafb4
--- /dev/null
+++ b/src/test/ui/match/match-tag-unary.rs
@@ -0,0 +1,4 @@
+enum A { A(isize) }
+enum B { B(isize) }
+
+fn main() { let x: A = A::A(0); match x { B::B(y) => { } } } //~ ERROR mismatched types
diff --git a/src/test/ui/match/match-tag-unary.stderr b/src/test/ui/match/match-tag-unary.stderr
new file mode 100644
index 000000000..31f77bdff
--- /dev/null
+++ b/src/test/ui/match/match-tag-unary.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> $DIR/match-tag-unary.rs:4:43
+ |
+LL | fn main() { let x: A = A::A(0); match x { B::B(y) => { } } }
+ | - ^^^^^^^ expected enum `A`, found enum `B`
+ | |
+ | this expression has type `A`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/match/match-type-err-first-arm.rs b/src/test/ui/match/match-type-err-first-arm.rs
new file mode 100644
index 000000000..e9027eb24
--- /dev/null
+++ b/src/test/ui/match/match-type-err-first-arm.rs
@@ -0,0 +1,50 @@
+fn main() {
+ let _ = test_func1(1);
+ let _ = test_func2(1);
+}
+
+fn test_func1(n: i32) -> i32 { //~ NOTE expected `i32` because of return type
+ match n {
+ 12 => 'b',
+ //~^ ERROR mismatched types
+ //~| NOTE expected `i32`, found `char`
+ _ => 42,
+ }
+}
+
+fn test_func2(n: i32) -> i32 {
+ let x = match n { //~ NOTE `match` arms have incompatible types
+ 12 => 'b', //~ NOTE this is found to be of type `char`
+ _ => 42,
+ //~^ ERROR `match` arms have incompatible types
+ //~| NOTE expected `char`, found integer
+ };
+ x
+}
+
+fn test_func3(n: i32) -> i32 {
+ let x = match n { //~ NOTE `match` arms have incompatible types
+ 1 => 'b',
+ 2 => 'b',
+ 3 => 'b',
+ 4 => 'b',
+ 5 => 'b',
+ 6 => 'b',
+ //~^ NOTE this and all prior arms are found to be of type `char`
+ _ => 42,
+ //~^ ERROR `match` arms have incompatible types
+ //~| NOTE expected `char`, found integer
+ };
+ x
+}
+
+fn test_func4() {
+ match Some(0u32) { //~ NOTE `match` arms have incompatible types
+ Some(x) => {
+ x //~ NOTE this is found to be of type `u32`
+ },
+ None => {}
+ //~^ ERROR `match` arms have incompatible types
+ //~| NOTE expected `u32`, found `()`
+ };
+}
diff --git a/src/test/ui/match/match-type-err-first-arm.stderr b/src/test/ui/match/match-type-err-first-arm.stderr
new file mode 100644
index 000000000..1cfe7ce1e
--- /dev/null
+++ b/src/test/ui/match/match-type-err-first-arm.stderr
@@ -0,0 +1,65 @@
+error[E0308]: mismatched types
+ --> $DIR/match-type-err-first-arm.rs:8:15
+ |
+LL | fn test_func1(n: i32) -> i32 {
+ | --- expected `i32` because of return type
+LL | match n {
+LL | 12 => 'b',
+ | ^^^ expected `i32`, found `char`
+ |
+help: you can cast a `char` to an `i32`, since a `char` always occupies 4 bytes
+ |
+LL | 12 => 'b' as i32,
+ | ++++++
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/match-type-err-first-arm.rs:18:14
+ |
+LL | let x = match n {
+ | _____________-
+LL | | 12 => 'b',
+ | | --- this is found to be of type `char`
+LL | | _ => 42,
+ | | ^^ expected `char`, found integer
+LL | |
+LL | |
+LL | | };
+ | |_____- `match` arms have incompatible types
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/match-type-err-first-arm.rs:34:14
+ |
+LL | let x = match n {
+ | _____________-
+LL | | 1 => 'b',
+LL | | 2 => 'b',
+LL | | 3 => 'b',
+... |
+LL | | 6 => 'b',
+ | | --- this and all prior arms are found to be of type `char`
+LL | |
+LL | | _ => 42,
+ | | ^^ expected `char`, found integer
+LL | |
+LL | |
+LL | | };
+ | |_____- `match` arms have incompatible types
+
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/match-type-err-first-arm.rs:46:17
+ |
+LL | / match Some(0u32) {
+LL | | Some(x) => {
+LL | | x
+ | | - this is found to be of type `u32`
+LL | | },
+LL | | None => {}
+ | | ^^ expected `u32`, found `()`
+LL | |
+LL | |
+LL | | };
+ | |_____- `match` arms have incompatible types
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/match/match-unresolved-one-arm.rs b/src/test/ui/match/match-unresolved-one-arm.rs
new file mode 100644
index 000000000..fa65d87b3
--- /dev/null
+++ b/src/test/ui/match/match-unresolved-one-arm.rs
@@ -0,0 +1,7 @@
+fn foo<T>() -> T { panic!("Rocks for my pillow") }
+
+fn main() {
+ let x = match () { //~ ERROR type annotations needed
+ () => foo() // T here should be unresolved
+ };
+}
diff --git a/src/test/ui/match/match-unresolved-one-arm.stderr b/src/test/ui/match/match-unresolved-one-arm.stderr
new file mode 100644
index 000000000..9eadb88a8
--- /dev/null
+++ b/src/test/ui/match/match-unresolved-one-arm.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/match-unresolved-one-arm.rs:4:9
+ |
+LL | let x = match () {
+ | ^
+ |
+help: consider giving `x` an explicit type
+ |
+LL | let x: _ = match () {
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/match/match-vec-mismatch-2.rs b/src/test/ui/match/match-vec-mismatch-2.rs
new file mode 100644
index 000000000..553095837
--- /dev/null
+++ b/src/test/ui/match/match-vec-mismatch-2.rs
@@ -0,0 +1,6 @@
+fn main() {
+ match () {
+ [()] => { }
+ //~^ ERROR expected an array or slice, found `()`
+ }
+}
diff --git a/src/test/ui/match/match-vec-mismatch-2.stderr b/src/test/ui/match/match-vec-mismatch-2.stderr
new file mode 100644
index 000000000..5247bea62
--- /dev/null
+++ b/src/test/ui/match/match-vec-mismatch-2.stderr
@@ -0,0 +1,9 @@
+error[E0529]: expected an array or slice, found `()`
+ --> $DIR/match-vec-mismatch-2.rs:3:9
+ |
+LL | [()] => { }
+ | ^^^^ pattern cannot match with input type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0529`.
diff --git a/src/test/ui/match/match-wildcards.rs b/src/test/ui/match/match-wildcards.rs
new file mode 100644
index 000000000..43f6e4913
--- /dev/null
+++ b/src/test/ui/match/match-wildcards.rs
@@ -0,0 +1,21 @@
+// run-fail
+// error-pattern:squirrelcupcake
+// ignore-emscripten no processes
+
+fn cmp() -> isize {
+ match (Some('a'), None::<char>) {
+ (Some(_), _) => {
+ panic!("squirrelcupcake");
+ }
+ (_, Some(_)) => {
+ panic!();
+ }
+ _ => {
+ panic!("wat");
+ }
+ }
+}
+
+fn main() {
+ println!("{}", cmp());
+}
diff --git a/src/test/ui/match/match_non_exhaustive.rs b/src/test/ui/match/match_non_exhaustive.rs
new file mode 100644
index 000000000..8219f0eb1
--- /dev/null
+++ b/src/test/ui/match/match_non_exhaustive.rs
@@ -0,0 +1,32 @@
+// aux-build:match_non_exhaustive_lib.rs
+
+/* The error message for non-exhaustive matches on non-local enums
+ * marked as non-exhaustive should mention the fact that the enum
+ * is marked as non-exhaustive (issue #85227).
+ */
+
+// Ignore non_exhaustive in the same crate
+#[non_exhaustive]
+enum L { A, B }
+
+extern crate match_non_exhaustive_lib;
+use match_non_exhaustive_lib::{E1, E2};
+
+fn foo() -> L {todo!()}
+fn bar() -> (E1, E2) {todo!()}
+
+fn main() {
+ let l = foo();
+ // No error for enums defined in this crate
+ match l { L::A => (), L::B => () };
+ // (except if the match is already non-exhaustive)
+ match l { L::A => () };
+ //~^ ERROR: non-exhaustive patterns: `B` not covered [E0004]
+
+ // E1 is not visibly uninhabited from here
+ let (e1, e2) = bar();
+ match e1 {};
+ //~^ ERROR: non-exhaustive patterns: type `E1` is non-empty [E0004]
+ match e2 { E2::A => (), E2::B => () };
+ //~^ ERROR: non-exhaustive patterns: `_` not covered [E0004]
+}
diff --git a/src/test/ui/match/match_non_exhaustive.stderr b/src/test/ui/match/match_non_exhaustive.stderr
new file mode 100644
index 000000000..9d92f8fdb
--- /dev/null
+++ b/src/test/ui/match/match_non_exhaustive.stderr
@@ -0,0 +1,56 @@
+error[E0004]: non-exhaustive patterns: `B` not covered
+ --> $DIR/match_non_exhaustive.rs:23:11
+ |
+LL | match l { L::A => () };
+ | ^ pattern `B` not covered
+ |
+note: `L` defined here
+ --> $DIR/match_non_exhaustive.rs:10:13
+ |
+LL | enum L { A, B }
+ | - ^ not covered
+ = note: the matched value is of type `L`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+LL | match l { L::A => (), B => todo!() };
+ | ++++++++++++++
+
+error[E0004]: non-exhaustive patterns: type `E1` is non-empty
+ --> $DIR/match_non_exhaustive.rs:28:11
+ |
+LL | match e1 {};
+ | ^^
+ |
+note: `E1` defined here
+ --> $DIR/auxiliary/match_non_exhaustive_lib.rs:2:1
+ |
+LL | pub enum E1 {}
+ | ^^^^^^^^^^^
+ = note: the matched value is of type `E1`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ match e1 {
+LL + _ => todo!(),
+LL ~ };
+ |
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/match_non_exhaustive.rs:30:11
+ |
+LL | match e2 { E2::A => (), E2::B => () };
+ | ^^ pattern `_` not covered
+ |
+note: `E2` defined here
+ --> $DIR/auxiliary/match_non_exhaustive_lib.rs:5:1
+ |
+LL | pub enum E2 { A, B }
+ | ^^^^^^^^^^^
+ = note: the matched value is of type `E2`, which is marked as non-exhaustive
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+LL | match e2 { E2::A => (), E2::B => (), _ => todo!() };
+ | ++++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/match/pattern-deref-miscompile.rs b/src/test/ui/match/pattern-deref-miscompile.rs
new file mode 100644
index 000000000..caa6d184a
--- /dev/null
+++ b/src/test/ui/match/pattern-deref-miscompile.rs
@@ -0,0 +1,46 @@
+// run-pass
+
+fn main() {
+ match b"." as &[u8] {
+ b"." if true => {},
+ b"." => panic!(),
+ b".." => panic!(),
+ b"" => panic!(),
+ _ => panic!(),
+ }
+ match b"." as &[u8] {
+ b"." if false => panic!(),
+ b"." => {},
+ b".." => panic!(),
+ b"" => panic!(),
+ _ => panic!(),
+ }
+ match b".." as &[u8] {
+ b"." if true => panic!(), // the miscompile caused this arm to be reached
+ b"." => panic!(),
+ b".." => {},
+ b"" => panic!(),
+ _ => panic!(),
+ }
+ match b".." as &[u8] {
+ b"." if false => panic!(),
+ b"." => panic!(),
+ b".." => {},
+ b"" => panic!(),
+ _ => panic!(),
+ }
+ match b"" as &[u8] {
+ b"." if true => panic!(),
+ b"." => panic!(),
+ b".." => panic!(),
+ b"" => {},
+ _ => panic!(),
+ }
+ match b"" as &[u8] {
+ b"." if false => panic!(),
+ b"." => panic!(),
+ b".." => panic!(),
+ b"" => {},
+ _ => panic!(),
+ }
+}