remove a hack that seems to only benefit a few very special cases
This commit is contained in:
parent
bd837e899b
commit
99a44ed086
|
@ -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::<qualifs::HasMutInterior>(place.local);
|
||||
// HACK(eddyb) this should compute the same thing as
|
||||
// `<HasMutInterior as Qualif>::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::<qualifs::NeedsDrop>(place.local) {
|
||||
return Err(Unpromotable);
|
||||
}
|
||||
|
||||
// FIXME(eddyb) this duplicates part of `validate_rvalue`.
|
||||
let has_mut_interior =
|
||||
self.qualif_local::<qualifs::HasMutInterior>(place.local);
|
||||
if has_mut_interior {
|
||||
return Err(Unpromotable);
|
||||
}
|
||||
if self.qualif_local::<qualifs::NeedsDrop>(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
|
||||
// `<HasMutInterior as Qualif>::in_projection` from
|
||||
// `check_consts::qualifs` but without recursion.
|
||||
let mut has_mut_interior =
|
||||
self.qualif_local::<qualifs::HasMutInterior>(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::<qualifs::HasMutInterior>(place.local);
|
||||
if has_mut_interior {
|
||||
return Err(Unpromotable);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
Loading…
Reference in a new issue