about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2019-11-24 22:39:05 +0000
committerMatthew Jasper <mjjasper1@gmail.com>2019-11-24 22:39:05 +0000
commit294f7e479019d574dc4083cc9603e92957cc6368 (patch)
treeb266b8a9ac79b1a259920d4fae9cd518a9c758cc
parent5a1d028d4c8fc15473dc10473c38df162daa7b41 (diff)
downloadrust-294f7e479019d574dc4083cc9603e92957cc6368.tar.gz
rust-294f7e479019d574dc4083cc9603e92957cc6368.zip
Handle non_exhaustive in borrow checking
-rw-r--r--src/librustc_mir/build/matches/simplify.rs2
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs8
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs42
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs18
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr15
5 files changed, 84 insertions, 1 deletions
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index 9b7bccca2dd..3e71b871801 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -164,7 +164,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         self.hir.tcx().features().exhaustive_patterns &&
                         !v.uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind()).is_empty()
                     }
-                });
+                }) && (adt_def.did.is_local() || !adt_def.is_variant_list_non_exhaustive());
                 if irrefutable {
                     let place = tcx.mk_place_downcast(match_pair.place, adt_def, variant_index);
                     candidate.match_pairs.extend(self.field_match_pairs(place, subpatterns));
diff --git a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs
new file mode 100644
index 00000000000..5f86db86d44
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs
@@ -0,0 +1,8 @@
+#[non_exhaustive]
+pub enum NonExhaustiveMonovariant {
+    Variant(u32),
+}
+
+pub enum ExhaustiveMonovariant {
+    Variant(u32),
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
new file mode 100644
index 00000000000..be775b37f7b
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
@@ -0,0 +1,42 @@
+// Test that the borrow checker doesn't consider checking an exhaustive pattern
+// as an access.
+
+// check-pass
+
+// aux-build:monovariants.rs
+extern crate monovariants;
+
+use monovariants::ExhaustiveMonovariant;
+
+enum Local {
+    Variant(u32),
+}
+
+#[non_exhaustive]
+enum LocalNonExhaustive {
+    Variant(u32),
+}
+
+fn main() {
+    let mut x = ExhaustiveMonovariant::Variant(1);
+    let y = &mut x;
+    match x {
+        ExhaustiveMonovariant::Variant(_) => {},
+        _ => {},
+    }
+    drop(y);
+    let mut x = Local::Variant(1);
+    let y = &mut x;
+    match x {
+        Local::Variant(_) => {},
+        _ => {},
+    }
+    drop(y);
+    let mut x = LocalNonExhaustive::Variant(1);
+    let y = &mut x;
+    match x {
+        LocalNonExhaustive::Variant(_) => {},
+        _ => {},
+    }
+    drop(y);
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs b/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs
new file mode 100644
index 00000000000..00dcf89c7aa
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs
@@ -0,0 +1,18 @@
+// Test that the borrow checker considers `#[non_exhaustive]` when checking
+// whether a match contains a discriminant read.
+
+// aux-build:monovariants.rs
+extern crate monovariants;
+
+use monovariants::NonExhaustiveMonovariant;
+
+fn main() {
+    let mut x = NonExhaustiveMonovariant::Variant(1);
+    let y = &mut x;
+    match x {
+        NonExhaustiveMonovariant::Variant(_) => {},
+        //~^ ERROR cannot use `x` because it was mutably borrowed
+        _ => {},
+    }
+    drop(y);
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr b/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr
new file mode 100644
index 00000000000..9edfa84cbc0
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr
@@ -0,0 +1,15 @@
+error[E0503]: cannot use `x` because it was mutably borrowed
+  --> $DIR/borrowck-non-exhaustive.rs:13:9
+   |
+LL |     let y = &mut x;
+   |             ------ borrow of `x` occurs here
+LL |     match x {
+LL |         NonExhaustiveMonovariant::Variant(_) => {},
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of borrowed `x`
+...
+LL |     drop(y);
+   |          - borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0503`.