From 99a44ed086978339d531aa40f84efdaa1bacbb45 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 25 Oct 2020 18:06:41 +0100 Subject: [PATCH] remove a hack that seems to only benefit a few very special cases --- .../rustc_mir/src/transform/promote_consts.rs | 58 ++----------------- src/test/ui/consts/promote-not.rs | 9 ++- src/test/ui/consts/promote-not.stderr | 25 +++++++- 3 files changed, 37 insertions(+), 55 deletions(-) diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs index 927aae82a36..8d5ed747c3f 100644 --- a/compiler/rustc_mir/src/transform/promote_consts.rs +++ b/compiler/rustc_mir/src/transform/promote_consts.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, List, TyCtxt, TypeFoldable}; use rustc_span::symbol::sym; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use rustc_index::vec::{Idx, IndexVec}; use rustc_target::spec::abi::Abi; @@ -326,41 +326,16 @@ impl<'tcx> Validator<'_, 'tcx> { if place.projection.contains(&ProjectionElem::Deref) { return Err(Unpromotable); } - - let mut has_mut_interior = - self.qualif_local::(place.local); - // HACK(eddyb) this should compute the same thing as - // `::in_projection` from - // `check_consts::qualifs` but without recursion. - if has_mut_interior { - // This allows borrowing fields which don't have - // `HasMutInterior`, from a type that does, e.g.: - // `let _: &'static _ = &(Cell::new(1), 2).1;` - let mut place_projection = &place.projection[..]; - // FIXME(eddyb) use a forward loop instead of a reverse one. - while let &[ref proj_base @ .., elem] = place_projection { - // FIXME(eddyb) this is probably excessive, with - // the exception of `union` member accesses. - let ty = - Place::ty_from(place.local, proj_base, self.body, self.tcx) - .projection_ty(self.tcx, elem) - .ty; - if ty.is_freeze(self.tcx.at(DUMMY_SP), self.param_env) { - has_mut_interior = false; - break; - } - - place_projection = proj_base; - } + if self.qualif_local::(place.local) { + return Err(Unpromotable); } // FIXME(eddyb) this duplicates part of `validate_rvalue`. + let has_mut_interior = + self.qualif_local::(place.local); if has_mut_interior { return Err(Unpromotable); } - if self.qualif_local::(place.local) { - return Err(Unpromotable); - } if let BorrowKind::Mut { .. } = kind { let ty = place.ty(self.body, self.tcx).ty; @@ -692,28 +667,7 @@ impl<'tcx> Validator<'_, 'tcx> { self.validate_place(place)?; - // HACK(eddyb) this should compute the same thing as - // `::in_projection` from - // `check_consts::qualifs` but without recursion. - let mut has_mut_interior = - self.qualif_local::(place.local); - if has_mut_interior { - let mut place_projection = place.projection; - // FIXME(eddyb) use a forward loop instead of a reverse one. - while let &[ref proj_base @ .., elem] = place_projection { - // FIXME(eddyb) this is probably excessive, with - // the exception of `union` member accesses. - let ty = Place::ty_from(place.local, proj_base, self.body, self.tcx) - .projection_ty(self.tcx, elem) - .ty; - if ty.is_freeze(self.tcx.at(DUMMY_SP), self.param_env) { - has_mut_interior = false; - break; - } - - place_projection = proj_base; - } - } + let has_mut_interior = self.qualif_local::(place.local); if has_mut_interior { return Err(Unpromotable); } diff --git a/src/test/ui/consts/promote-not.rs b/src/test/ui/consts/promote-not.rs index a7938fabad5..1e4d8586b87 100644 --- a/src/test/ui/consts/promote-not.rs +++ b/src/test/ui/consts/promote-not.rs @@ -34,7 +34,14 @@ const TEST_UNION: () = { let _x: &'static i32 = &unsafe { U { x: 0 }.x }; //~ ERROR temporary value dropped while borrowed }; +// In a `const`, we do not promote things with interior mutability. Not even if we "project it away". +const TEST_INTERIOR_MUT: () = { + // The "0." case is already ruled out by not permitting any interior mutability in `const`. + let _val: &'static _ = &(Cell::new(1), 2).1; //~ ERROR temporary value dropped while borrowed +}; + fn main() { - // We must not promote things with interior mutability. + // We must not promote things with interior mutability. Not even if we "project it away". let _val: &'static _ = &(Cell::new(1), 2).0; //~ ERROR temporary value dropped while borrowed + let _val: &'static _ = &(Cell::new(1), 2).1; //~ ERROR temporary value dropped while borrowed } diff --git a/src/test/ui/consts/promote-not.stderr b/src/test/ui/consts/promote-not.stderr index 2698424c165..6e76d9ee6c1 100644 --- a/src/test/ui/consts/promote-not.stderr +++ b/src/test/ui/consts/promote-not.stderr @@ -49,15 +49,36 @@ LL | }; | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promote-not.rs:39:29 + --> $DIR/promote-not.rs:40:29 + | +LL | let _val: &'static _ = &(Cell::new(1), 2).1; + | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` +LL | }; + | - temporary value is freed at the end of this statement + +error[E0716]: temporary value dropped while borrowed + --> $DIR/promote-not.rs:45:29 | LL | let _val: &'static _ = &(Cell::new(1), 2).0; | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use | | | type annotation requires that borrow lasts for `'static` +LL | let _val: &'static _ = &(Cell::new(1), 2).1; +LL | } + | - temporary value is freed at the end of this statement + +error[E0716]: temporary value dropped while borrowed + --> $DIR/promote-not.rs:46:29 + | +LL | let _val: &'static _ = &(Cell::new(1), 2).1; + | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use + | | + | type annotation requires that borrow lasts for `'static` LL | } | - temporary value is freed at the end of this statement -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0716`.