about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2018-11-21 10:42:40 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2018-11-21 10:42:40 +0100
commit3c290a5326755d5f978caf66cfd61b05652169d5 (patch)
tree524979fd1cee2c938fb601716b81dbf77a5a5f03
parent301ce8b2aa6156ae8dc535ca234e95b04e7c4e4b (diff)
downloadrust-3c290a5326755d5f978caf66cfd61b05652169d5.tar.gz
rust-3c290a5326755d5f978caf66cfd61b05652169d5.zip
Ensure assignments don't allow skipping projection checks
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs11
-rw-r--r--src/test/ui/consts/projection_qualif.rs14
-rw-r--r--src/test/ui/consts/projection_qualif.stderr18
3 files changed, 42 insertions, 1 deletions
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 51e590fe292..571fe998970 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -252,7 +252,16 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
                     // projections are transparent for assignments
                     // we qualify the entire destination at once, even if just a field would have
                     // stricter qualification
-                    Place::Projection(proj) => dest = &proj.base,
+                    Place::Projection(proj) => {
+                        // Catch more errors in the destination. `visit_place` also checks various
+                        // projection rules like union field access and raw pointer deref
+                        self.visit_place(
+                            dest,
+                            PlaceContext::MutatingUse(MutatingUseContext::Store),
+                            location
+                        );
+                        dest = &proj.base;
+                    },
                     Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"),
                     Place::Static(..) => {
                         // Catch more errors in the destination. `visit_place` also checks that we
diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/projection_qualif.rs
new file mode 100644
index 00000000000..4806fecee43
--- /dev/null
+++ b/src/test/ui/consts/projection_qualif.rs
@@ -0,0 +1,14 @@
+#![feature(const_let)]
+
+use std::cell::Cell;
+
+const FOO: &u32 = {
+    let mut a = 42;
+    {
+        let b: *mut u32 = &mut a; //~ ERROR may only refer to immutable values
+        unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants
+    }
+    &{a}
+};
+
+fn main() {}
\ No newline at end of file
diff --git a/src/test/ui/consts/projection_qualif.stderr b/src/test/ui/consts/projection_qualif.stderr
new file mode 100644
index 00000000000..d5252f199be
--- /dev/null
+++ b/src/test/ui/consts/projection_qualif.stderr
@@ -0,0 +1,18 @@
+error[E0017]: references in constants may only refer to immutable values
+  --> $DIR/projection_qualif.rs:8:27
+   |
+LL |         let b: *mut u32 = &mut a; //~ ERROR may only refer to immutable values
+   |                           ^^^^^^ constants require immutable values
+
+error[E0658]: dereferencing raw pointers in constants is unstable (see issue #51911)
+  --> $DIR/projection_qualif.rs:9:18
+   |
+LL |         unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants
+   |                  ^^^^^^
+   |
+   = help: add #![feature(const_raw_ptr_deref)] to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0017, E0658.
+For more information about an error, try `rustc --explain E0017`.