From 3c290a5326755d5f978caf66cfd61b05652169d5 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 21 Nov 2018 10:42:40 +0100 Subject: [PATCH] Ensure assignments don't allow skipping projection checks --- src/librustc_mir/transform/qualify_consts.rs | 11 ++++++++++- src/test/ui/consts/projection_qualif.rs | 14 ++++++++++++++ src/test/ui/consts/projection_qualif.stderr | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/projection_qualif.rs create mode 100644 src/test/ui/consts/projection_qualif.stderr diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 51e590fe2929..571fe9989705 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 000000000000..4806fecee431 --- /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 000000000000..d5252f199bea --- /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`.