summaryrefslogtreecommitdiffstats
path: root/src/test/ui/closures/2229_closure_analysis/match
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/closures/2229_closure_analysis/match
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/closures/2229_closure_analysis/match')
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/auxiliary/match_non_exhaustive_lib.rs10
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/issue-87097.rs35
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr36
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/issue-87426.rs14
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/issue-87988.rs19
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/issue-88331.rs33
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/issue-88331.stderr39
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs44
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs37
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr17
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs54
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr70
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs79
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr83
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs137
-rw-r--r--src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr203
16 files changed, 910 insertions, 0 deletions
diff --git a/src/test/ui/closures/2229_closure_analysis/match/auxiliary/match_non_exhaustive_lib.rs b/src/test/ui/closures/2229_closure_analysis/match/auxiliary/match_non_exhaustive_lib.rs
new file mode 100644
index 000000000..4060c4093
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/auxiliary/match_non_exhaustive_lib.rs
@@ -0,0 +1,10 @@
+#[non_exhaustive]
+pub enum E1 {}
+
+#[non_exhaustive]
+pub enum E2 { A, B }
+
+#[non_exhaustive]
+pub enum E3 { C }
+
+pub enum E4 { D }
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.rs b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.rs
new file mode 100644
index 000000000..815fc0a71
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.rs
@@ -0,0 +1,35 @@
+// run-pass
+// edition:2021
+
+enum Variant {
+ A,
+ B, //~ WARNING: variant `B` is never constructed
+}
+
+struct A {
+ field: Variant,
+}
+
+fn discriminant_is_a_ref() {
+ let here = A { field: Variant::A };
+ let out_ref = &here.field;
+
+ || match out_ref { //~ WARNING: unused closure that must be used
+ Variant::A => (),
+ Variant::B => (),
+ };
+}
+
+fn discriminant_is_a_field() {
+ let here = A { field: Variant::A };
+
+ || match here.field { //~ WARNING: unused closure that must be used
+ Variant::A => (),
+ Variant::B => (),
+ };
+}
+
+fn main() {
+ discriminant_is_a_ref();
+ discriminant_is_a_field();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
new file mode 100644
index 000000000..2a49ed4b5
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
@@ -0,0 +1,36 @@
+warning: variant `B` is never constructed
+ --> $DIR/issue-87097.rs:6:5
+ |
+LL | enum Variant {
+ | ------- variant in this enum
+LL | A,
+LL | B,
+ | ^
+ |
+ = note: `#[warn(dead_code)]` on by default
+
+warning: unused closure that must be used
+ --> $DIR/issue-87097.rs:17:5
+ |
+LL | / || match out_ref {
+LL | | Variant::A => (),
+LL | | Variant::B => (),
+LL | | };
+ | |______^
+ |
+ = note: `#[warn(unused_must_use)]` on by default
+ = note: closures are lazy and do nothing unless called
+
+warning: unused closure that must be used
+ --> $DIR/issue-87097.rs:26:5
+ |
+LL | / || match here.field {
+LL | | Variant::A => (),
+LL | | Variant::B => (),
+LL | | };
+ | |______^
+ |
+ = note: closures are lazy and do nothing unless called
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-87426.rs b/src/test/ui/closures/2229_closure_analysis/match/issue-87426.rs
new file mode 100644
index 000000000..74506979a
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-87426.rs
@@ -0,0 +1,14 @@
+// run-pass
+// edition:2021
+
+pub fn foo() {
+ let ref_x_ck = 123;
+ let _y = || match ref_x_ck {
+ 2_000_000..=3_999_999 => { println!("A")}
+ _ => { println!("B")}
+ };
+}
+
+fn main() {
+ foo();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-87988.rs b/src/test/ui/closures/2229_closure_analysis/match/issue-87988.rs
new file mode 100644
index 000000000..27e7fabf1
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-87988.rs
@@ -0,0 +1,19 @@
+// run-pass
+// edition:2021
+
+const LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: i32 = 0x01;
+const LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: i32 = 0x02;
+
+pub fn hotplug_callback(event: i32) {
+ let _ = || {
+ match event {
+ LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED => (),
+ LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT => (),
+ _ => (),
+ };
+ };
+}
+
+fn main() {
+ hotplug_callback(1);
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-88331.rs b/src/test/ui/closures/2229_closure_analysis/match/issue-88331.rs
new file mode 100644
index 000000000..0a6d71c68
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-88331.rs
@@ -0,0 +1,33 @@
+// edition:2021
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub struct Opcode(pub u8);
+
+impl Opcode {
+ pub const OP1: Opcode = Opcode(0x1);
+}
+
+pub fn example1(msg_type: Opcode) -> impl FnMut(&[u8]) {
+ move |i| match msg_type {
+ //~^ ERROR: non-exhaustive patterns: `Opcode(0_u8)` and `Opcode(2_u8..=u8::MAX)` not covered
+ Opcode::OP1 => unimplemented!(),
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub struct Opcode2(Opcode);
+
+impl Opcode2 {
+ pub const OP2: Opcode2 = Opcode2(Opcode(0x1));
+}
+
+
+pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
+
+ move |i| match msg_type {
+ //~^ ERROR: non-exhaustive patterns: `Opcode2(Opcode(0_u8))` and `Opcode2(Opcode(2_u8..=u8::MAX))` not covered
+ Opcode2::OP2=> unimplemented!(),
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-88331.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-88331.stderr
new file mode 100644
index 000000000..7e22defa9
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/issue-88331.stderr
@@ -0,0 +1,39 @@
+error[E0004]: non-exhaustive patterns: `Opcode(0_u8)` and `Opcode(2_u8..=u8::MAX)` not covered
+ --> $DIR/issue-88331.rs:11:20
+ |
+LL | move |i| match msg_type {
+ | ^^^^^^^^ patterns `Opcode(0_u8)` and `Opcode(2_u8..=u8::MAX)` not covered
+ |
+note: `Opcode` defined here
+ --> $DIR/issue-88331.rs:4:12
+ |
+LL | pub struct Opcode(pub u8);
+ | ^^^^^^
+ = note: the matched value is of type `Opcode`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+ |
+LL ~ Opcode::OP1 => unimplemented!(),
+LL ~ Opcode(0_u8) | Opcode(2_u8..=u8::MAX) => todo!(),
+ |
+
+error[E0004]: non-exhaustive patterns: `Opcode2(Opcode(0_u8))` and `Opcode2(Opcode(2_u8..=u8::MAX))` not covered
+ --> $DIR/issue-88331.rs:27:20
+ |
+LL | move |i| match msg_type {
+ | ^^^^^^^^ patterns `Opcode2(Opcode(0_u8))` and `Opcode2(Opcode(2_u8..=u8::MAX))` not covered
+ |
+note: `Opcode2` defined here
+ --> $DIR/issue-88331.rs:18:12
+ |
+LL | pub struct Opcode2(Opcode);
+ | ^^^^^^^
+ = note: the matched value is of type `Opcode2`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+ |
+LL ~ Opcode2::OP2=> unimplemented!(),
+LL ~ Opcode2(Opcode(0_u8)) | Opcode2(Opcode(2_u8..=u8::MAX)) => todo!(),
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs
new file mode 100644
index 000000000..914ebbe26
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_1.rs
@@ -0,0 +1,44 @@
+// run-pass
+// edition:2021
+
+const PATTERN_REF: &str = "Hello World";
+const NUMBER: i32 = 30;
+const NUMBER_POINTER: *const i32 = &NUMBER;
+
+pub fn edge_case_ref(event: &str) {
+ let _ = || {
+ match event {
+ PATTERN_REF => (),
+ _ => (),
+ };
+ };
+}
+
+pub fn edge_case_str(event: String) {
+ let _ = || {
+ match event.as_str() {
+ "hello" => (),
+ _ => (),
+ };
+ };
+}
+
+pub fn edge_case_raw_ptr(event: *const i32) {
+ let _ = || {
+ match event {
+ NUMBER_POINTER => (),
+ _ => (),
+ };
+ };
+}
+
+pub fn edge_case_char(event: char) {
+ let _ = || {
+ match event {
+ 'a' => (),
+ _ => (),
+ };
+ };
+}
+
+fn main() {}
diff --git a/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs
new file mode 100644
index 000000000..ae724f9c3
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs
@@ -0,0 +1,37 @@
+// edition:2021
+
+enum SingleVariant {
+ A
+}
+
+struct TestStruct {
+ x: i32,
+ y: i32,
+ z: i32,
+}
+
+fn edge_case_if() {
+ let sv = SingleVariant::A;
+ let condition = true;
+ // sv should not be captured as it is a SingleVariant
+ let _a = || {
+ match sv {
+ SingleVariant::A if condition => (),
+ _ => ()
+ }
+ };
+ let mut mut_sv = sv;
+ _a();
+
+ // ts should be captured
+ let ts = TestStruct { x: 1, y: 1, z: 1 };
+ let _b = || { match ts {
+ TestStruct{ x: 1, .. } => (),
+ _ => ()
+ }};
+ let mut mut_ts = ts;
+ //~^ ERROR: cannot move out of `ts` because it is borrowed
+ _b();
+}
+
+fn main() {}
diff --git a/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr
new file mode 100644
index 000000000..1e42d73c6
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr
@@ -0,0 +1,17 @@
+error[E0505]: cannot move out of `ts` because it is borrowed
+ --> $DIR/match-edge-cases_2.rs:32:22
+ |
+LL | let _b = || { match ts {
+ | -- -- borrow occurs due to use in closure
+ | |
+ | borrow of `ts` occurs here
+...
+LL | let mut mut_ts = ts;
+ | ^^ move out of `ts` occurs here
+LL |
+LL | _b();
+ | -- borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0505`.
diff --git a/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs
new file mode 100644
index 000000000..318673ef8
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs
@@ -0,0 +1,54 @@
+// edition:2021
+
+// 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 L1 { A, B }
+enum L2 { C }
+
+extern crate match_non_exhaustive_lib;
+use match_non_exhaustive_lib::{E1, E2, E3, E4};
+
+fn foo() -> (L1, L2) {todo!()}
+fn bar() -> (E1, E2, E3, E4) {todo!()}
+
+fn main() {
+ let (l1, l2) = foo();
+ // No error for enums defined in this crate
+ let _a = || { match l1 { L1::A => (), L1::B => () } };
+ // (except if the match is already non-exhaustive)
+ let _b = || { match l1 { L1::A => () } };
+ //~^ ERROR: non-exhaustive patterns: `B` not covered [E0004]
+
+ // l2 should not be captured as it is a non-exhaustive SingleVariant
+ // defined in this crate
+ let _c = || { match l2 { L2::C => (), _ => () } };
+ let mut mut_l2 = l2;
+ _c();
+
+ // E1 is not visibly uninhabited from here
+ let (e1, e2, e3, e4) = bar();
+ let _d = || { match e1 {} };
+ //~^ ERROR: non-exhaustive patterns: type `E1` is non-empty [E0004]
+ let _e = || { match e2 { E2::A => (), E2::B => () } };
+ //~^ ERROR: non-exhaustive patterns: `_` not covered [E0004]
+ let _f = || { match e2 { E2::A => (), E2::B => (), _ => () } };
+
+ // e3 should be captured as it is a non-exhaustive SingleVariant
+ // defined in another crate
+ let _g = || { match e3 { E3::C => (), _ => () } };
+ let mut mut_e3 = e3;
+ //~^ ERROR: cannot move out of `e3` because it is borrowed
+ _g();
+
+ // e4 should not be captured as it is a SingleVariant
+ let _h = || { match e4 { E4::D => (), _ => () } };
+ let mut mut_e4 = e4;
+ _h();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
new file mode 100644
index 000000000..e0678bc71
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
@@ -0,0 +1,70 @@
+error[E0004]: non-exhaustive patterns: `B` not covered
+ --> $DIR/non-exhaustive-match.rs:26:25
+ |
+LL | let _b = || { match l1 { L1::A => () } };
+ | ^^ pattern `B` not covered
+ |
+note: `L1` defined here
+ --> $DIR/non-exhaustive-match.rs:12:14
+ |
+LL | enum L1 { A, B }
+ | -- ^ not covered
+ = note: the matched value is of type `L1`
+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 | let _b = || { match l1 { L1::A => (), B => todo!() } };
+ | ++++++++++++++
+
+error[E0004]: non-exhaustive patterns: type `E1` is non-empty
+ --> $DIR/non-exhaustive-match.rs:37:25
+ |
+LL | let _d = || { 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 ~ let _d = || { match e1 {
+LL + _ => todo!(),
+LL ~ } };
+ |
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+ --> $DIR/non-exhaustive-match.rs:39:25
+ |
+LL | let _e = || { 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 | let _e = || { match e2 { E2::A => (), E2::B => (), _ => todo!() } };
+ | ++++++++++++++
+
+error[E0505]: cannot move out of `e3` because it is borrowed
+ --> $DIR/non-exhaustive-match.rs:46:22
+ |
+LL | let _g = || { match e3 { E3::C => (), _ => () } };
+ | -- -- borrow occurs due to use in closure
+ | |
+ | borrow of `e3` occurs here
+LL | let mut mut_e3 = e3;
+ | ^^ move out of `e3` occurs here
+LL |
+LL | _g();
+ | -- borrow later used here
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0004, E0505.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs
new file mode 100644
index 000000000..69cf920de
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs
@@ -0,0 +1,79 @@
+// edition:2021
+
+#![feature(never_type)]
+
+// Should fake read the discriminant and throw an error
+fn test1() {
+ let x: !;
+ let c1 = || match x { };
+ //~^ ERROR E0381
+}
+
+// Should fake read the discriminant and throw an error
+fn test2() {
+ let x: !;
+ let c2 = || match x { _ => () };
+ //~^ ERROR E0381
+}
+
+// Testing single variant patterns
+enum SingleVariant {
+ Points(u32)
+}
+
+// Should fake read the discriminant and throw an error
+fn test3() {
+ let variant: !;
+ let c = || {
+ //~^ ERROR E0381
+ match variant {
+ SingleVariant::Points(_) => {}
+ }
+ };
+ c();
+}
+
+// Should fake read the discriminant and throw an error
+fn test4() {
+ let variant: !;
+ let c = || { //~ ERROR E0381
+ match variant {
+ SingleVariant::Points(a) => {
+ println!("{:?}", a);
+ }
+ }
+ };
+ c();
+}
+
+fn test5() {
+ let t: !;
+ let g: !;
+
+ let a = || {
+ match g { }; //~ ERROR E0381
+ let c = || {
+ match t { }; //~ ERROR E0381
+ };
+
+ c();
+ };
+
+}
+
+// Should fake read the discriminant and throw an error
+fn test6() {
+ let x: u8;
+ let c1 = || match x { };
+ //~^ ERROR E0381
+ //~| ERROR: non-exhaustive patterns: type `u8` is non-empty
+}
+
+fn main() {
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
new file mode 100644
index 000000000..fea5441ec
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
@@ -0,0 +1,83 @@
+error[E0004]: non-exhaustive patterns: type `u8` is non-empty
+ --> $DIR/pattern-matching-should-fail.rs:67:23
+ |
+LL | let c1 = || match x { };
+ | ^
+ |
+ = note: the matched value is of type `u8`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+ |
+LL ~ let c1 = || match x {
+LL + _ => todo!(),
+LL ~ };
+ |
+
+error[E0381]: used binding `x` isn't initialized
+ --> $DIR/pattern-matching-should-fail.rs:8:23
+ |
+LL | let x: !;
+ | - binding declared here but left uninitialized
+LL | let c1 = || match x { };
+ | ^ `x` used here but it isn't initialized
+
+error[E0381]: used binding `x` isn't initialized
+ --> $DIR/pattern-matching-should-fail.rs:15:14
+ |
+LL | let x: !;
+ | - binding declared here but left uninitialized
+LL | let c2 = || match x { _ => () };
+ | ^^ - borrow occurs due to use in closure
+ | |
+ | `x` used here but it isn't initialized
+
+error[E0381]: used binding `variant` isn't initialized
+ --> $DIR/pattern-matching-should-fail.rs:27:13
+ |
+LL | let variant: !;
+ | ------- binding declared here but left uninitialized
+LL | let c = || {
+ | ^^ `variant` used here but it isn't initialized
+LL |
+LL | match variant {
+ | ------- borrow occurs due to use in closure
+
+error[E0381]: used binding `variant` isn't initialized
+ --> $DIR/pattern-matching-should-fail.rs:39:13
+ |
+LL | let variant: !;
+ | ------- binding declared here but left uninitialized
+LL | let c = || {
+ | ^^ `variant` used here but it isn't initialized
+LL | match variant {
+ | ------- borrow occurs due to use in closure
+
+error[E0381]: used binding `g` isn't initialized
+ --> $DIR/pattern-matching-should-fail.rs:54:15
+ |
+LL | let g: !;
+ | - binding declared here but left uninitialized
+...
+LL | match g { };
+ | ^ `g` used here but it isn't initialized
+
+error[E0381]: used binding `t` isn't initialized
+ --> $DIR/pattern-matching-should-fail.rs:56:19
+ |
+LL | let t: !;
+ | - binding declared here but left uninitialized
+...
+LL | match t { };
+ | ^ `t` used here but it isn't initialized
+
+error[E0381]: used binding `x` isn't initialized
+ --> $DIR/pattern-matching-should-fail.rs:67:23
+ |
+LL | let x: u8;
+ | - binding declared here but left uninitialized
+LL | let c1 = || match x { };
+ | ^ `x` used here but it isn't initialized
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0004, E0381.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs b/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs
new file mode 100644
index 000000000..56f5ac44d
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs
@@ -0,0 +1,137 @@
+// edition:2021
+
+#![feature(rustc_attrs)]
+
+// Should capture the discriminant since a variant of a multivariant enum is
+// mentioned in the match arm; the discriminant is captured by the closure regardless
+// of if it creates a binding
+fn test_1_should_capture() {
+ let variant = Some(2229);
+ let c = #[rustc_capture_analysis]
+ //~^ ERROR: attributes on expressions are experimental
+ //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+
+ || {
+ //~^ First Pass analysis includes:
+ //~| Min Capture analysis includes:
+ match variant {
+ //~^ NOTE: Capturing variant[] -> ImmBorrow
+ //~| NOTE: Min Capture variant[] -> ImmBorrow
+ Some(_) => {}
+ _ => {}
+ }
+ };
+ c();
+}
+
+// Should not capture the discriminant since only a wildcard is mentioned in the
+// match arm
+fn test_2_should_not_capture() {
+ let variant = Some(2229);
+ let c = #[rustc_capture_analysis]
+ //~^ ERROR: attributes on expressions are experimental
+ //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+ || {
+ //~^ First Pass analysis includes:
+ match variant {
+ _ => {}
+ }
+ };
+ c();
+}
+
+// Testing single variant patterns
+enum SingleVariant {
+ Points(u32)
+}
+
+// Should not capture the discriminant since the single variant mentioned
+// in the match arm does not trigger a binding
+fn test_3_should_not_capture_single_variant() {
+ let variant = SingleVariant::Points(1);
+ let c = #[rustc_capture_analysis]
+ //~^ ERROR: attributes on expressions are experimental
+ //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+ || {
+ //~^ First Pass analysis includes:
+ match variant {
+ SingleVariant::Points(_) => {}
+ }
+ };
+ c();
+}
+
+// Should not capture the discriminant since the single variant mentioned
+// in the match arm does not trigger a binding
+fn test_6_should_capture_single_variant() {
+ let variant = SingleVariant::Points(1);
+ let c = #[rustc_capture_analysis]
+ //~^ ERROR: attributes on expressions are experimental
+ //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+ || {
+ //~^ First Pass analysis includes:
+ //~| Min Capture analysis includes:
+ match variant {
+ //~^ NOTE: Capturing variant[] -> ImmBorrow
+ //~| NOTE: Capturing variant[(0, 0)] -> ImmBorrow
+ //~| NOTE: Min Capture variant[] -> ImmBorrow
+ SingleVariant::Points(a) => {
+ println!("{:?}", a);
+ }
+ }
+ };
+ c();
+}
+
+// Should not capture the discriminant since only wildcards are mentioned in the
+// match arm
+fn test_4_should_not_capture_array() {
+ let array: [i32; 3] = [0; 3];
+ let c = #[rustc_capture_analysis]
+ //~^ ERROR: attributes on expressions are experimental
+ //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+ || {
+ //~^ First Pass analysis includes:
+ match array {
+ [_,_,_] => {}
+ }
+ };
+ c();
+}
+
+// Testing MultiVariant patterns
+enum MVariant {
+ A,
+ B,
+ C,
+}
+
+// Should capture the discriminant since a variant of the multi variant enum is
+// mentioned in the match arm; the discriminant is captured by the closure
+// regardless of if it creates a binding
+fn test_5_should_capture_multi_variant() {
+ let variant = MVariant::A;
+ let c = #[rustc_capture_analysis]
+ //~^ ERROR: attributes on expressions are experimental
+ //~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
+ || {
+ //~^ First Pass analysis includes:
+ //~| Min Capture analysis includes:
+ match variant {
+ //~^ NOTE: Capturing variant[] -> ImmBorrow
+ //~| NOTE: Min Capture variant[] -> ImmBorrow
+ MVariant::A => {}
+ _ => {}
+ }
+ };
+ c();
+}
+
+fn main() {
+ test_1_should_capture();
+ test_2_should_not_capture();
+ test_3_should_not_capture_single_variant();
+ test_6_should_capture_single_variant();
+ test_4_should_not_capture_array();
+ test_5_should_capture_multi_variant();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr b/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr
new file mode 100644
index 000000000..460813333
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr
@@ -0,0 +1,203 @@
+error[E0658]: attributes on expressions are experimental
+ --> $DIR/patterns-capture-analysis.rs:10:14
+ |
+LL | let c = #[rustc_capture_analysis]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+ = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental
+ --> $DIR/patterns-capture-analysis.rs:31:14
+ |
+LL | let c = #[rustc_capture_analysis]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+ = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental
+ --> $DIR/patterns-capture-analysis.rs:52:14
+ |
+LL | let c = #[rustc_capture_analysis]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+ = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental
+ --> $DIR/patterns-capture-analysis.rs:68:14
+ |
+LL | let c = #[rustc_capture_analysis]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+ = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental
+ --> $DIR/patterns-capture-analysis.rs:90:14
+ |
+LL | let c = #[rustc_capture_analysis]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+ = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental
+ --> $DIR/patterns-capture-analysis.rs:114:14
+ |
+LL | let c = #[rustc_capture_analysis]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+ = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error: First Pass analysis includes:
+ --> $DIR/patterns-capture-analysis.rs:14:5
+ |
+LL | / || {
+LL | |
+LL | |
+LL | | match variant {
+... |
+LL | | }
+LL | | };
+ | |_____^
+ |
+note: Capturing variant[] -> ImmBorrow
+ --> $DIR/patterns-capture-analysis.rs:17:15
+ |
+LL | match variant {
+ | ^^^^^^^
+
+error: Min Capture analysis includes:
+ --> $DIR/patterns-capture-analysis.rs:14:5
+ |
+LL | / || {
+LL | |
+LL | |
+LL | | match variant {
+... |
+LL | | }
+LL | | };
+ | |_____^
+ |
+note: Min Capture variant[] -> ImmBorrow
+ --> $DIR/patterns-capture-analysis.rs:17:15
+ |
+LL | match variant {
+ | ^^^^^^^
+
+error: First Pass analysis includes:
+ --> $DIR/patterns-capture-analysis.rs:34:5
+ |
+LL | / || {
+LL | |
+LL | | match variant {
+LL | | _ => {}
+LL | | }
+LL | | };
+ | |_____^
+
+error: First Pass analysis includes:
+ --> $DIR/patterns-capture-analysis.rs:55:5
+ |
+LL | / || {
+LL | |
+LL | | match variant {
+LL | | SingleVariant::Points(_) => {}
+LL | | }
+LL | | };
+ | |_____^
+
+error: First Pass analysis includes:
+ --> $DIR/patterns-capture-analysis.rs:71:5
+ |
+LL | / || {
+LL | |
+LL | |
+LL | | match variant {
+... |
+LL | | }
+LL | | };
+ | |_____^
+ |
+note: Capturing variant[] -> ImmBorrow
+ --> $DIR/patterns-capture-analysis.rs:74:15
+ |
+LL | match variant {
+ | ^^^^^^^
+note: Capturing variant[(0, 0)] -> ImmBorrow
+ --> $DIR/patterns-capture-analysis.rs:74:15
+ |
+LL | match variant {
+ | ^^^^^^^
+
+error: Min Capture analysis includes:
+ --> $DIR/patterns-capture-analysis.rs:71:5
+ |
+LL | / || {
+LL | |
+LL | |
+LL | | match variant {
+... |
+LL | | }
+LL | | };
+ | |_____^
+ |
+note: Min Capture variant[] -> ImmBorrow
+ --> $DIR/patterns-capture-analysis.rs:74:15
+ |
+LL | match variant {
+ | ^^^^^^^
+
+error: First Pass analysis includes:
+ --> $DIR/patterns-capture-analysis.rs:93:5
+ |
+LL | / || {
+LL | |
+LL | | match array {
+LL | | [_,_,_] => {}
+LL | | }
+LL | | };
+ | |_____^
+
+error: First Pass analysis includes:
+ --> $DIR/patterns-capture-analysis.rs:117:5
+ |
+LL | / || {
+LL | |
+LL | |
+LL | | match variant {
+... |
+LL | | }
+LL | | };
+ | |_____^
+ |
+note: Capturing variant[] -> ImmBorrow
+ --> $DIR/patterns-capture-analysis.rs:120:15
+ |
+LL | match variant {
+ | ^^^^^^^
+
+error: Min Capture analysis includes:
+ --> $DIR/patterns-capture-analysis.rs:117:5
+ |
+LL | / || {
+LL | |
+LL | |
+LL | | match variant {
+... |
+LL | | }
+LL | | };
+ | |_____^
+ |
+note: Min Capture variant[] -> ImmBorrow
+ --> $DIR/patterns-capture-analysis.rs:120:15
+ |
+LL | match variant {
+ | ^^^^^^^
+
+error: aborting due to 15 previous errors
+
+For more information about this error, try `rustc --explain E0658`.