about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/expr_use_visitor.rs7
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-88331.rs33
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-88331.stderr27
3 files changed, 67 insertions, 0 deletions
diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index cd00d181ed0..e7c3a366cc4 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -267,6 +267,13 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                                 if let ty::Adt(def, _) = place_ty.kind() {
                                     if def.variants.len() > 1 {
                                         needs_to_be_read = true;
+                                    } else if let Some(variant) = def.variants.iter().next() {
+                                        // If the pat kind is a Path we want to check whether the
+                                        // variant contains at least one field. If that's the case,
+                                        // we want to borrow discr.
+                                        if matches!(pat.kind, PatKind::Path(..)) && variant.fields.len() > 0 {
+                                            needs_to_be_read = true;
+                                        }
                                     }
                                 } else {
                                     // If it is not ty::Adt, then it should be read
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-88331.rs b/src/test/ui/closures/2229_closure_analysis/issue-88331.rs
new file mode 100644
index 00000000000..0a6d71c68ae
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/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/issue-88331.stderr b/src/test/ui/closures/2229_closure_analysis/issue-88331.stderr
new file mode 100644
index 00000000000..f02d23464f1
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-88331.stderr
@@ -0,0 +1,27 @@
+error[E0004]: non-exhaustive patterns: `Opcode(0_u8)` and `Opcode(2_u8..=u8::MAX)` not covered
+  --> $DIR/issue-88331.rs:11:20
+   |
+LL | pub struct Opcode(pub u8);
+   | -------------------------- `Opcode` defined here
+...
+LL |     move |i| match msg_type {
+   |                    ^^^^^^^^ patterns `Opcode(0_u8)` and `Opcode(2_u8..=u8::MAX)` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Opcode`
+
+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 | pub struct Opcode2(Opcode);
+   | --------------------------- `Opcode2` defined here
+...
+LL |     move |i| match msg_type {
+   |                    ^^^^^^^^ patterns `Opcode2(Opcode(0_u8))` and `Opcode2(Opcode(2_u8..=u8::MAX))` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Opcode2`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.