1
Fork 0

Remove Static from PlaceBase

This commit is contained in:
Santiago Pastorino 2019-12-11 10:39:24 -03:00 committed by Oliver Scherer
parent 9e70c47783
commit fd5aa32c35
37 changed files with 192 additions and 451 deletions

View file

@ -1655,7 +1655,7 @@ impl Debug for Statement<'_> {
/// changing or disturbing program state.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)]
pub struct Place<'tcx> {
pub base: PlaceBase<'tcx>,
pub base: PlaceBase,
/// projection out of a place (access a field, deref a pointer, etc)
pub projection: &'tcx List<PlaceElem<'tcx>>,
@ -1664,34 +1664,9 @@ pub struct Place<'tcx> {
impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)]
pub enum PlaceBase<'tcx> {
pub enum PlaceBase {
/// local variable
Local(Local),
/// static or static mut variable
Static(Box<Static<'tcx>>),
}
/// We store the normalized type to avoid requiring normalization when reading MIR
#[derive(
Clone,
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
RustcEncodable,
RustcDecodable,
HashStable
)]
pub struct Static<'tcx> {
pub ty: Ty<'tcx>,
/// The `DefId` of the item this static was declared in. For promoted values, usually, this is
/// the same as the `DefId` of the `mir::Body` containing the `Place` this promoted appears in.
/// However, after inlining, that might no longer be the case as inlined `Place`s are copied
/// into the calling frame.
pub def_id: DefId,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -1781,7 +1756,7 @@ rustc_index::newtype_index! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PlaceRef<'a, 'tcx> {
pub base: &'a PlaceBase<'tcx>,
pub base: &'a PlaceBase,
pub projection: &'a [PlaceElem<'tcx>],
}
@ -1830,7 +1805,7 @@ impl From<Local> for Place<'_> {
}
}
impl From<Local> for PlaceBase<'_> {
impl From<Local> for PlaceBase {
fn from(local: Local) -> Self {
PlaceBase::Local(local)
}
@ -1921,13 +1896,10 @@ impl Debug for Place<'_> {
}
}
impl Debug for PlaceBase<'_> {
impl Debug for PlaceBase {
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
match *self {
PlaceBase::Local(id) => write!(fmt, "{:?}", id),
PlaceBase::Static(box self::Static { ty, def_id }) => {
write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty)
}
}
}
}
@ -3000,18 +2972,16 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for PlaceBase<'tcx> {
impl<'tcx> TypeFoldable<'tcx> for PlaceBase {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
match self {
PlaceBase::Local(local) => PlaceBase::Local(local.fold_with(folder)),
PlaceBase::Static(static_) => PlaceBase::Static(static_.fold_with(folder)),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match self {
PlaceBase::Local(local) => local.visit_with(visitor),
PlaceBase::Static(static_) => (**static_).visit_with(visitor),
}
}
}
@ -3027,18 +2997,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
}
}
impl<'tcx> TypeFoldable<'tcx> for Static<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
Static { ty: self.ty.fold_with(folder), def_id: self.def_id }
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
let Static { ty, def_id: _ } = self;
ty.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
use crate::mir::Rvalue::*;

View file

@ -114,7 +114,7 @@ impl<'tcx> PlaceTy<'tcx> {
impl<'tcx> Place<'tcx> {
pub fn ty_from<D>(
base: &PlaceBase<'tcx>,
base: &PlaceBase,
projection: &[PlaceElem<'tcx>],
local_decls: &D,
tcx: TyCtxt<'tcx>,
@ -135,14 +135,13 @@ impl<'tcx> Place<'tcx> {
}
}
impl<'tcx> PlaceBase<'tcx> {
impl<'tcx> PlaceBase {
pub fn ty<D>(&self, local_decls: &D) -> PlaceTy<'tcx>
where
D: HasLocalDecls<'tcx>,
{
match self {
PlaceBase::Local(index) => PlaceTy::from_ty(local_decls.local_decls()[*index].ty),
PlaceBase::Static(data) => PlaceTy::from_ty(data.ty),
}
}
}

View file

@ -164,7 +164,7 @@ macro_rules! make_mir_visitor {
}
fn visit_place_base(&mut self,
base: & $($mutability)? PlaceBase<'tcx>,
base: & $($mutability)? PlaceBase,
context: PlaceContext,
location: Location) {
self.super_place_base(base, context, location);
@ -705,16 +705,13 @@ macro_rules! make_mir_visitor {
}
fn super_place_base(&mut self,
place_base: & $($mutability)? PlaceBase<'tcx>,
place_base: & $($mutability)? PlaceBase,
context: PlaceContext,
location: Location) {
match place_base {
PlaceBase::Local(local) => {
self.visit_local(local, context, location);
}
PlaceBase::Static(box Static { ty, def_id: _ }) => {
self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
}
}
}
@ -889,7 +886,7 @@ macro_rules! visit_place_fns {
() => (
fn visit_projection(
&mut self,
base: &PlaceBase<'tcx>,
base: &PlaceBase,
projection: &[PlaceElem<'tcx>],
context: PlaceContext,
location: Location,
@ -899,7 +896,7 @@ macro_rules! visit_place_fns {
fn visit_projection_elem(
&mut self,
base: &PlaceBase<'tcx>,
base: &PlaceBase,
proj_base: &[PlaceElem<'tcx>],
elem: &PlaceElem<'tcx>,
context: PlaceContext,
@ -934,7 +931,7 @@ macro_rules! visit_place_fns {
fn super_projection(
&mut self,
base: &PlaceBase<'tcx>,
base: &PlaceBase,
projection: &[PlaceElem<'tcx>],
context: PlaceContext,
location: Location,
@ -948,7 +945,7 @@ macro_rules! visit_place_fns {
fn super_projection_elem(
&mut self,
_base: &PlaceBase<'tcx>,
_base: &PlaceBase,
_proj_base: &[PlaceElem<'tcx>],
elem: &PlaceElem<'tcx>,
_context: PlaceContext,

View file

@ -226,7 +226,7 @@ pub fn decode_place<D>(decoder: &mut D) -> Result<mir::Place<'tcx>, D::Error>
where
D: TyDecoder<'tcx>,
{
let base: mir::PlaceBase<'tcx> = Decodable::decode(decoder)?;
let base: mir::PlaceBase = Decodable::decode(decoder)?;
let len = decoder.read_usize()?;
let projection: &'tcx List<mir::PlaceElem<'tcx>> =
decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?;

View file

@ -14,7 +14,6 @@ use rustc::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
use rustc_span::DUMMY_SP;
pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx: &FunctionCx<'a, 'tcx, Bx>,
@ -135,10 +134,10 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
// ZSTs don't require any actual memory access.
let elem_ty = base_ty.projection_ty(cx.tcx(), elem).ty;
let elem_ty = self.fx.monomorphize(&elem_ty);
let span = if let mir::PlaceBase::Local(index) = place_ref.base {
self.fx.mir.local_decls[*index].source_info.span
} else {
DUMMY_SP
let span = match place_ref.base {
mir::PlaceBase::Local(index) => {
self.fx.mir.local_decls[*index].source_info.span
}
};
if cx.spanned_layout_of(elem_ty, span).is_zst() {
return;
@ -179,8 +178,8 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
// We use `NonUseContext::VarDebugInfo` for the base,
// which might not force the base local to memory,
// so we have to do it manually.
if let mir::PlaceBase::Local(local) = place_ref.base {
self.visit_local(&local, context, location);
match place_ref.base {
mir::PlaceBase::Local(local) => self.visit_local(&local, context, location),
}
}
}

View file

@ -258,8 +258,8 @@ pub fn per_local_var_debug_info(
if tcx.sess.opts.debuginfo == DebugInfo::Full || !tcx.sess.fewer_names() {
let mut per_local = IndexVec::from_elem(vec![], &body.local_decls);
for var in &body.var_debug_info {
if let mir::PlaceBase::Local(local) = var.place.base {
per_local[local].push(var);
match var.place.base {
mir::PlaceBase::Local(local) => per_local[local].push(var),
}
}
Some(per_local)

View file

@ -373,44 +373,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) -> Option<OperandRef<'tcx, Bx::Value>> {
debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref);
if let mir::PlaceBase::Local(index) = place_ref.base {
match self.locals[*index] {
LocalRef::Operand(Some(mut o)) => {
// Moves out of scalar and scalar pair fields are trivial.
for elem in place_ref.projection.iter() {
match elem {
mir::ProjectionElem::Field(ref f, _) => {
o = o.extract_field(bx, f.index());
}
mir::ProjectionElem::Index(_)
| mir::ProjectionElem::ConstantIndex { .. } => {
// ZSTs don't require any actual memory access.
// FIXME(eddyb) deduplicate this with the identical
// checks in `codegen_consume` and `extract_field`.
let elem = o.layout.field(bx.cx(), 0);
if elem.is_zst() {
o = OperandRef::new_zst(bx, elem);
} else {
return None;
match place_ref.base {
mir::PlaceBase::Local(index) => {
match self.locals[*index] {
LocalRef::Operand(Some(mut o)) => {
// Moves out of scalar and scalar pair fields are trivial.
for elem in place_ref.projection.iter() {
match elem {
mir::ProjectionElem::Field(ref f, _) => {
o = o.extract_field(bx, f.index());
}
mir::ProjectionElem::Index(_)
| mir::ProjectionElem::ConstantIndex { .. } => {
// ZSTs don't require any actual memory access.
// FIXME(eddyb) deduplicate this with the identical
// checks in `codegen_consume` and `extract_field`.
let elem = o.layout.field(bx.cx(), 0);
if elem.is_zst() {
o = OperandRef::new_zst(bx, elem);
} else {
return None;
}
}
_ => return None,
}
_ => return None,
}
}
Some(o)
}
LocalRef::Operand(None) => {
bug!("use of {:?} before def", place_ref);
}
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
// watch out for locals that do not have an
// alloca; they are handled somewhat differently
None
Some(o)
}
LocalRef::Operand(None) => {
bug!("use of {:?} before def", place_ref);
}
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
// watch out for locals that do not have an
// alloca; they are handled somewhat differently
None
}
}
}
} else {
None
}
}

View file

@ -37,15 +37,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
PlaceRef { llval, llextra: None, layout, align }
}
fn new_thin_place<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
llval: V,
layout: TyLayout<'tcx>,
) -> PlaceRef<'tcx, V> {
assert!(!bx.cx().type_has_metadata(layout.ty));
PlaceRef { llval, llextra: None, layout, align: layout.align.abi }
}
// FIXME(eddyb) pass something else for the name so no work is done
// unless LLVM IR names are turned on (e.g. for `--emit=llvm-ir`).
pub fn alloca<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
@ -437,16 +428,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
mir::PlaceRef {
base: mir::PlaceBase::Static(box mir::Static { ty, def_id }),
projection: [],
} => {
// NB: The layout of a static may be unsized as is the case when working
// with a static that is an extern_type.
let layout = cx.layout_of(self.monomorphize(&ty));
let static_ = bx.get_static(*def_id);
PlaceRef::new_thin_place(bx, static_, layout)
}
mir::PlaceRef { base, projection: [proj_base @ .., mir::ProjectionElem::Deref] } => {
// Load the pointer from its location.
self.codegen_consume(bx, &mir::PlaceRef { base, projection: proj_base })

View file

@ -208,8 +208,10 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx);
if let mir::PlaceBase::Local(local) = borrowed_place.base {
self.local_map.entry(local).or_default().insert(idx);
match borrowed_place.base {
mir::PlaceBase::Local(local) => {
self.local_map.entry(local).or_default().insert(idx);
}
}
}

View file

@ -207,10 +207,6 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> {
);
}
PlaceRef { base: &PlaceBase::Static(_), .. } => {
// Ignore kills of static or static mut variables.
}
PlaceRef { base: &PlaceBase::Local(local), projection: &[.., _] } => {
// Kill conflicting borrows of the innermost local.
debug!(

View file

@ -688,7 +688,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
assert!(root_place.projection.is_empty());
let proper_span = match root_place.base {
PlaceBase::Local(local) => self.body.local_decls[*local].source_info.span,
_ => drop_span,
};
let root_place_projection = self.infcx.tcx.intern_place_elems(root_place.projection);
@ -709,12 +708,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow_span,
));
if let PlaceBase::Local(local) = borrow.borrowed_place.base {
if self.body.local_decls[local].is_ref_to_thread_local() {
let err = self
.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span);
err.buffer(&mut self.errors_buffer);
return;
match borrow.borrowed_place.base {
PlaceBase::Local(local) => {
if self.body.local_decls[local].is_ref_to_thread_local() {
let err = self.report_thread_local_value_does_not_live_long_enough(
drop_span,
borrow_span,
);
err.buffer(&mut self.errors_buffer);
return;
}
}
};

View file

@ -2,7 +2,7 @@
use rustc::mir::{
AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place,
PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Static, Terminator,
PlaceBase, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
TerminatorKind,
};
use rustc::ty::layout::VariantIdx;
@ -172,9 +172,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
PlaceRef { base: PlaceBase::Local(local), projection: [] } => {
self.append_local_to_string(*local, buf)?;
}
PlaceRef { base: PlaceBase::Static(box Static { def_id, .. }), projection: [] } => {
buf.push_str(&self.infcx.tcx.item_name(*def_id).to_string());
}
PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] }
if self.body.local_decls[local].is_ref_for_guard() =>
{
@ -318,9 +315,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let local = &self.body.local_decls[*local];
self.describe_field_from_ty(&local.ty, field, None)
}
PlaceRef { base: PlaceBase::Static(static_), projection: [] } => {
self.describe_field_from_ty(&static_.ty, field, None)
}
PlaceRef { base, projection: [proj_base @ .., elem] } => match elem {
ProjectionElem::Deref => {
self.describe_field(PlaceRef { base, projection: proj_base }, field)

View file

@ -243,9 +243,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
);
(
match kind {
IllegalMoveOriginKind::Static => {
unreachable!();
}
IllegalMoveOriginKind::BorrowedContent { target_place } => self
.report_cannot_move_from_borrowed_content(
original_path,

View file

@ -136,8 +136,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}
PlaceRef { base: PlaceBase::Static(_), .. }
| PlaceRef { base: _, projection: [.., ProjectionElem::Index(_)] }
PlaceRef { base: _, projection: [.., ProjectionElem::Index(_)] }
| PlaceRef { base: _, projection: [.., ProjectionElem::ConstantIndex { .. }] }
| PlaceRef { base: _, projection: [.., ProjectionElem::Subslice { .. }] }
| PlaceRef { base: _, projection: [.., ProjectionElem::Downcast(..)] } => {

View file

@ -5,7 +5,7 @@ use rustc::lint::builtin::MUTABLE_BORROW_RESERVATION_CONFLICT;
use rustc::lint::builtin::UNUSED_MUT;
use rustc::mir::{
read_only, Body, BodyAndCache, ClearCrossCrate, Local, Location, Mutability, Operand, Place,
PlaceBase, PlaceElem, PlaceRef, ReadOnlyBodyAndCache, Static,
PlaceBase, PlaceElem, PlaceRef, ReadOnlyBodyAndCache,
};
use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
@ -815,7 +815,7 @@ enum InitializationRequiringAction {
}
struct RootPlace<'d, 'tcx> {
place_base: &'d PlaceBase<'tcx>,
place_base: &'d PlaceBase,
place_projection: &'d [PlaceElem<'tcx>],
is_local_mutation_allowed: LocalMutationIsAllowed,
}
@ -1251,8 +1251,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some(field) = this.is_upvar_field_projection(place.as_ref()) {
this.used_mut_upvars.push(field);
}
} else if let PlaceBase::Local(local) = place.base {
this.used_mut.insert(local);
} else {
match place.base {
PlaceBase::Local(local) => {
this.used_mut.insert(local);
}
}
}
};
@ -1385,7 +1389,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// FIXME: allow thread-locals to borrow other thread locals?
let (might_be_alive, will_be_dropped) = match root_place.base {
PlaceBase::Static(_) => (true, false),
PlaceBase::Local(local) => {
if self.body.local_decls[*local].is_ref_to_thread_local() {
// Thread-locals might be dropped after the function exits
@ -1649,26 +1652,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// This code covers scenarios 1, 2, and 3.
debug!("check_if_full_path_is_moved place: {:?}", place_span.0);
match self.move_path_closest_to(place_span.0) {
Ok((prefix, mpi)) => {
if maybe_uninits.contains(mpi) {
self.report_use_of_moved_or_uninitialized(
location,
desired_action,
(prefix, place_span.0, place_span.1),
mpi,
);
}
}
Err(NoMovePathFound::ReachedStatic) => {
// Okay: we do not build MoveData for static variables
} // Only query longest prefix with a MovePath, not further
// ancestors; dataflow recurs on children when parents
// move (to support partial (re)inits).
//
// (I.e., querying parents breaks scenario 7; but may want
// to do such a query based on partial-init feature-gate.)
}
let (prefix, mpi) = self.move_path_closest_to(place_span.0);
if maybe_uninits.contains(mpi) {
self.report_use_of_moved_or_uninitialized(
location,
desired_action,
(prefix, place_span.0, place_span.1),
mpi,
);
} // Only query longest prefix with a MovePath, not further
// ancestors; dataflow recurs on children when parents
// move (to support partial (re)inits).
//
// (I.e., querying parents breaks scenario 7; but may want
// to do such a query based on partial-init feature-gate.)
}
/// Subslices correspond to multiple move paths, so we iterate through the
@ -1792,12 +1789,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn move_path_closest_to(
&mut self,
place: PlaceRef<'_, 'tcx>,
) -> Result<(PlaceRef<'cx, 'tcx>, MovePathIndex), NoMovePathFound> {
) -> (PlaceRef<'cx, 'tcx>, MovePathIndex) {
match self.move_data.rev_lookup.find(place) {
LookupResult::Parent(Some(mpi)) | LookupResult::Exact(mpi) => {
Ok((self.move_data.move_paths[mpi].place.as_ref(), mpi))
(self.move_data.move_paths[mpi].place.as_ref(), mpi)
}
LookupResult::Parent(None) => Err(NoMovePathFound::ReachedStatic),
LookupResult::Parent(None) => panic!("should have move path for every Local"),
}
}
@ -1881,7 +1878,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
projection: proj_base,
}, span, flow_state);
if let PlaceBase::Local(local) = place.base {
match place.base {
// rust-lang/rust#21232,
// #54499, #54986: during
// period where we reject
@ -1890,7 +1887,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// unnecessary `mut` on an
// attempt to do a partial
// initialization.
self.used_mut.insert(local);
PlaceBase::Local(local) => {
self.used_mut.insert(local);
}
}
}
@ -2088,10 +2087,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// partial initialization, do not complain about mutability
// errors except for actual mutation (as opposed to an attempt
// to do a partial initialization).
let previously_initialized = if let PlaceBase::Local(local) = place.base {
self.is_local_ever_initialized(local, flow_state).is_some()
} else {
true
let previously_initialized = match place.base {
PlaceBase::Local(local) => self.is_local_ever_initialized(local, flow_state).is_some(),
};
// at this point, we have set up the error reporting state.
@ -2152,11 +2149,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.used_mut_upvars.push(field);
}
}
RootPlace {
place_base: PlaceBase::Static(..),
place_projection: [],
is_local_mutation_allowed: _,
} => {}
}
}
@ -2191,17 +2183,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}),
}
}
PlaceRef { base: PlaceBase::Static(box Static { def_id, .. }), projection: [] } => {
if !self.infcx.tcx.is_mutable_static(*def_id) {
Err(place)
} else {
Ok(RootPlace {
place_base: place.base,
place_projection: place.projection,
is_local_mutation_allowed,
})
}
}
PlaceRef { base: _, projection: [proj_base @ .., elem] } => {
match elem {
ProjectionElem::Deref => {
@ -2356,11 +2337,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum NoMovePathFound {
ReachedStatic,
}
/// The degree of overlap between 2 places for borrow-checking.
enum Overlap {
/// The places might partially overlap - in this case, we give

View file

@ -132,8 +132,6 @@ pub(super) fn is_active<'tcx>(
/// This is called for all Yield expressions on movable generators
pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
match place.base {
PlaceBase::Static(_) => false,
// Reborrow of already borrowed data is ignored
// Any errors will be caught on the initial borrow
PlaceBase::Local(_) => !place.is_indirect(),

View file

@ -47,7 +47,6 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
}
}
},
PlaceBase::Static(_) => return true,
};
for (i, elem) in self.projection.iter().enumerate() {

View file

@ -122,7 +122,7 @@ fn place_components_conflict<'tcx>(
let borrow_base = &borrow_place.base;
let access_base = access_place.base;
match place_base_conflict(tcx, borrow_base, access_base) {
match place_base_conflict(borrow_base, access_base) {
Overlap::Arbitrary => {
bug!("Two base can't return Arbitrary");
}
@ -293,11 +293,7 @@ fn place_components_conflict<'tcx>(
// Given that the bases of `elem1` and `elem2` are always either equal
// or disjoint (and have the same type!), return the overlap situation
// between `elem1` and `elem2`.
fn place_base_conflict<'tcx>(
tcx: TyCtxt<'tcx>,
elem1: &PlaceBase<'tcx>,
elem2: &PlaceBase<'tcx>,
) -> Overlap {
fn place_base_conflict(elem1: &PlaceBase, elem2: &PlaceBase) -> Overlap {
match (elem1, elem2) {
(PlaceBase::Local(l1), PlaceBase::Local(l2)) => {
if l1 == l2 {
@ -310,24 +306,6 @@ fn place_base_conflict<'tcx>(
Overlap::Disjoint
}
}
(PlaceBase::Static(s1), PlaceBase::Static(s2)) => {
if s1.def_id != s2.def_id {
debug!("place_element_conflict: DISJOINT-STATIC");
Overlap::Disjoint
} else if tcx.is_mutable_static(s1.def_id) {
// We ignore mutable statics - they can only be unsafe code.
debug!("place_element_conflict: IGNORE-STATIC-MUT");
Overlap::Disjoint
} else {
debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC");
Overlap::EqualOrDisjoint
}
}
(PlaceBase::Local(_), PlaceBase::Static(_))
| (PlaceBase::Static(_), PlaceBase::Local(_)) => {
debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED");
Overlap::Disjoint
}
}
}
@ -337,7 +315,7 @@ fn place_base_conflict<'tcx>(
fn place_projection_conflict<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
pi1_base: &PlaceBase<'tcx>,
pi1_base: &PlaceBase,
pi1_proj_base: &[PlaceElem<'tcx>],
pi1_elem: &PlaceElem<'tcx>,
pi2_elem: &PlaceElem<'tcx>,

View file

@ -69,39 +69,22 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
'cursor: loop {
match &cursor {
PlaceRef {
base: PlaceBase::Local(_),
projection: [],
}
| // search yielded this leaf
PlaceRef {
base: PlaceBase::Static(_),
projection: [],
} => {
PlaceRef { base: PlaceBase::Local(_), projection: [] } => {
self.next = None;
return Some(cursor);
}
PlaceRef {
base: _,
projection: [proj_base @ .., elem],
} => {
PlaceRef { base: _, projection: [proj_base @ .., elem] } => {
match elem {
ProjectionElem::Field(_ /*field*/, _ /*ty*/) => {
// FIXME: add union handling
self.next = Some(PlaceRef {
base: cursor.base,
projection: proj_base,
});
self.next = Some(PlaceRef { base: cursor.base, projection: proj_base });
return Some(cursor);
}
ProjectionElem::Downcast(..) |
ProjectionElem::Subslice { .. } |
ProjectionElem::ConstantIndex { .. } |
ProjectionElem::Index(_) => {
cursor = PlaceRef {
base: cursor.base,
projection: proj_base,
};
ProjectionElem::Downcast(..)
| ProjectionElem::Subslice { .. }
| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Index(_) => {
cursor = PlaceRef { base: cursor.base, projection: proj_base };
continue 'cursor;
}
ProjectionElem::Deref => {
@ -122,10 +105,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
PrefixSet::All => {
// All prefixes: just blindly enqueue the base
// of the projection.
self.next = Some(PlaceRef {
base: cursor.base,
projection: proj_base,
});
self.next = Some(PlaceRef { base: cursor.base, projection: proj_base });
return Some(cursor);
}
PrefixSet::Supporting => {
@ -140,35 +120,20 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
let ty = Place::ty_from(cursor.base, proj_base, *self.body, self.tcx).ty;
match ty.kind {
ty::RawPtr(_) |
ty::Ref(
_, /*rgn*/
_, /*ty*/
hir::Mutability::Not
) => {
ty::RawPtr(_) | ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Not) => {
// don't continue traversing over derefs of raw pointers or shared
// borrows.
self.next = None;
return Some(cursor);
}
ty::Ref(
_, /*rgn*/
_, /*ty*/
hir::Mutability::Mut,
) => {
self.next = Some(PlaceRef {
base: cursor.base,
projection: proj_base,
});
ty::Ref(_ /*rgn*/, _ /*ty*/, hir::Mutability::Mut) => {
self.next = Some(PlaceRef { base: cursor.base, projection: proj_base });
return Some(cursor);
}
ty::Adt(..) if ty.is_box() => {
self.next = Some(PlaceRef {
base: cursor.base,
projection: proj_base,
});
self.next = Some(PlaceRef { base: cursor.base, projection: proj_base });
return Some(cursor);
}

View file

@ -467,32 +467,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
let mut place_ty = match &place.base {
PlaceBase::Local(index) => PlaceTy::from_ty(self.body.local_decls[*index].ty),
PlaceBase::Static(box Static { ty, def_id }) => {
let san_ty = self.sanitize_type(place, ty);
let check_err =
|verifier: &mut TypeVerifier<'a, 'b, 'tcx>, place: &Place<'tcx>, ty, san_ty| {
if let Err(terr) = verifier.cx.eq_types(
san_ty,
ty,
location.to_locations(),
ConstraintCategory::Boring,
) {
span_mirbug!(
verifier,
place,
"bad promoted type ({:?}: {:?}): {:?}",
ty,
san_ty,
terr
);
};
};
let ty = self.tcx().type_of(*def_id);
let ty = self.cx.normalize(ty, location);
check_err(self, place, ty, san_ty);
PlaceTy::from_ty(san_ty)
}
};
if place.projection.is_empty() {

View file

@ -57,8 +57,10 @@ impl GatherUsedMutsVisitor<'_, '_, '_> {
// be those that were never initialized - we will consider those as being used as
// they will either have been removed by unreachable code optimizations; or linted
// as unused variables.
if let PlaceBase::Local(local) = into.base {
let _ = self.never_initialized_mut_locals.remove(&local);
match into.base {
PlaceBase::Local(local) => {
self.never_initialized_mut_locals.remove(&local);
}
}
}
}
@ -80,12 +82,12 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) {
match &statement.kind {
StatementKind::Assign(box (into, _)) => {
if let PlaceBase::Local(local) = into.base {
debug!(
match into.base {
PlaceBase::Local(local) => debug!(
"visit_statement: statement={:?} local={:?} \
never_initialized_mut_locals={:?}",
never_initialized_mut_locals={:?}",
statement, local, self.never_initialized_mut_locals
);
),
}
self.remove_never_initialized_mut_locals(into);
}

View file

@ -20,7 +20,7 @@ use rustc_index::vec::Idx;
/// and `c` can be progressively pushed onto the place builder that is created when converting `a`.
#[derive(Clone)]
struct PlaceBuilder<'tcx> {
base: PlaceBase<'tcx>,
base: PlaceBase,
projection: Vec<PlaceElem<'tcx>>,
}
@ -53,8 +53,8 @@ impl From<Local> for PlaceBuilder<'tcx> {
}
}
impl From<PlaceBase<'tcx>> for PlaceBuilder<'tcx> {
fn from(base: PlaceBase<'tcx>) -> Self {
impl From<PlaceBase> for PlaceBuilder<'tcx> {
fn from(base: PlaceBase) -> Self {
Self { base, projection: Vec::new() }
}
}

View file

@ -195,35 +195,37 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
fn kill_borrows_on_place(&self, trans: &mut GenKillSet<BorrowIndex>, place: &Place<'tcx>) {
debug!("kill_borrows_on_place: place={:?}", place);
if let PlaceBase::Local(local) = place.base {
let other_borrows_of_local =
self.borrow_set.local_map.get(&local).into_iter().flat_map(|bs| bs.into_iter());
match place.base {
PlaceBase::Local(local) => {
let other_borrows_of_local =
self.borrow_set.local_map.get(&local).into_iter().flat_map(|bs| bs.into_iter());
// If the borrowed place is a local with no projections, all other borrows of this
// local must conflict. This is purely an optimization so we don't have to call
// `places_conflict` for every borrow.
if place.projection.is_empty() {
if !self.body.local_decls[local].is_ref_to_static() {
trans.kill_all(other_borrows_of_local);
// If the borrowed place is a local with no projections, all other borrows of this
// local must conflict. This is purely an optimization so we don't have to call
// `places_conflict` for every borrow.
if place.projection.is_empty() {
if !self.body.local_decls[local].is_ref_to_static() {
trans.kill_all(other_borrows_of_local);
}
return;
}
return;
// By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given
// pair of array indices are unequal, so that when `places_conflict` returns true, we
// will be assured that two places being compared definitely denotes the same sets of
// locations.
let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| {
places_conflict(
self.tcx,
self.body,
&self.borrow_set.borrows[i].borrowed_place,
place,
PlaceConflictBias::NoOverlap,
)
});
trans.kill_all(definitely_conflicting_borrows);
}
// By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given
// pair of array indices are unequal, so that when `places_conflict` returns true, we
// will be assured that two places being compared definitely denotes the same sets of
// locations.
let definitely_conflicting_borrows = other_borrows_of_local.filter(|&&i| {
places_conflict(
self.tcx,
self.body,
&self.borrow_set.borrows[i].borrowed_place,
place,
PlaceConflictBias::NoOverlap,
)
});
trans.kill_all(definitely_conflicting_borrows);
}
}
}

View file

@ -115,15 +115,13 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
match stmt.kind {
StatementKind::StorageDead(l) => sets.kill(l),
StatementKind::Assign(box (ref place, _))
| StatementKind::SetDiscriminant { box ref place, .. } => {
if let PlaceBase::Local(local) = place.base {
sets.gen(local);
}
}
| StatementKind::SetDiscriminant { box ref place, .. } => match place.base {
PlaceBase::Local(local) => sets.gen(local),
},
StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => {
for p in &**outputs {
if let PlaceBase::Local(local) = p.base {
sets.gen(local);
match p.base {
PlaceBase::Local(local) => sets.gen(local),
}
}
}
@ -171,8 +169,10 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
_dest_bb: mir::BasicBlock,
dest_place: &mir::Place<'tcx>,
) {
if let PlaceBase::Local(local) = dest_place.base {
in_out.insert(local);
match dest_place.base {
PlaceBase::Local(local) => {
in_out.insert(local);
}
}
}
}

View file

@ -98,9 +98,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
debug!("lookup({:?})", place);
let mut base = match place.base {
PlaceBase::Local(local) => self.builder.data.rev_lookup.locals[local],
PlaceBase::Static(..) => {
return Err(MoveError::cannot_move_out_of(self.loc, Static));
}
};
// The move path index of the first union that we find. Once this is

View file

@ -248,7 +248,6 @@ impl MovePathLookup {
pub fn find(&self, place: PlaceRef<'_, '_>) -> LookupResult {
let mut result = match place.base {
PlaceBase::Local(local) => self.locals[*local],
PlaceBase::Static(..) => return LookupResult::Parent(None),
};
for elem in place.projection.iter() {
@ -281,9 +280,6 @@ pub struct IllegalMoveOrigin<'tcx> {
#[derive(Debug)]
pub(crate) enum IllegalMoveOriginKind<'tcx> {
/// Illegal move due to attempt to move from `static` variable.
Static,
/// Illegal move due to attempt to move from behind a reference.
BorrowedContent {
/// The place the reference refers to: if erroneous code was trying to

View file

@ -474,7 +474,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.access_local(self.frame(), *local, layout)?
}
PlaceBase::Static(place_static) => self.eval_static_to_mplace(&place_static)?.into(),
};
let op = place

View file

@ -10,7 +10,6 @@ use rustc::mir::interpret::truncate;
use rustc::ty::layout::{
self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx,
};
use rustc::ty::TypeFoldable;
use rustc::ty::{self, Ty};
use rustc_macros::HashStable;
@ -619,35 +618,6 @@ where
})
}
/// Evaluate statics and promoteds to an `MPlace`. Used to share some code between
/// `eval_place` and `eval_place_to_op`.
pub(super) fn eval_static_to_mplace(
&self,
place_static: &mir::Static<'tcx>,
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
let ty = place_static.ty;
assert!(!ty.needs_subst());
let layout = self.layout_of(ty)?;
// Just create a lazy reference, so we can support recursive statics.
// tcx takes care of assigning every static one and only one unique AllocId.
// When the data here is ever actually used, memory will notice,
// and it knows how to deal with alloc_id that are present in the
// global table but not in its local memory: It calls back into tcx through
// a query, triggering the CTFE machinery to actually turn this lazy reference
// into a bunch of bytes. IOW, statics are evaluated with CTFE even when
// this InterpCx uses another Machine (e.g., in miri). This is what we
// want! This way, computing statics works consistently between codegen
// and miri: They use the same query to eventually obtain a `ty::Const`
// and use that for further computation.
//
// Notice that statics have *two* AllocIds: the lazy one, and the resolved
// one. Here we make sure that the interpreted program never sees the
// resolved ID. Also see the doc comment of `Memory::get_static_alloc`.
let alloc_id = self.tcx.alloc_map.lock().create_static_alloc(place_static.def_id);
let ptr = self.tag_static_base_pointer(Pointer::from(alloc_id));
Ok(MPlaceTy::from_aligned_ptr(ptr, layout))
}
/// Computes a place. You should only use this if you intend to write into this
/// place; for reading, a more efficient alternative is `eval_place_for_read`.
pub fn eval_place(
@ -683,7 +653,6 @@ where
place: Place::Local { frame: self.cur_frame(), local: *local },
layout: self.layout_of_local(self.frame(), *local, None)?,
},
PlaceBase::Static(place_static) => self.eval_static_to_mplace(&place_static)?.into(),
};
for elem in place.projection.iter() {

View file

@ -182,7 +182,7 @@ use rustc::mir::interpret::{AllocId, ConstValue};
use rustc::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar};
use rustc::mir::mono::{InstantiationMode, MonoItem};
use rustc::mir::visit::Visitor as MirVisitor;
use rustc::mir::{self, Location, PlaceBase, Static};
use rustc::mir::{self, Location, PlaceBase};
use rustc::session::config::EntryFnType;
use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast};
use rustc::ty::print::obsolete::DefPathBasedNames;
@ -642,20 +642,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
fn visit_place_base(
&mut self,
place_base: &mir::PlaceBase<'tcx>,
place_base: &mir::PlaceBase,
_context: mir::visit::PlaceContext,
location: Location,
_location: Location,
) {
match place_base {
PlaceBase::Static(box Static { def_id, .. }) => {
debug!("visiting static {:?} @ {:?}", def_id, location);
let tcx = self.tcx;
let instance = Instance::mono(tcx, *def_id);
if should_monomorphize_locally(tcx, &instance) {
self.output.push(MonoItem::Static(*def_id));
}
}
PlaceBase::Local(_) => {
// Locals have no relevance for collector.
}

View file

@ -76,9 +76,6 @@ pub trait Qualif {
) -> bool {
match place {
PlaceRef { base: PlaceBase::Local(local), projection: [] } => per_local(*local),
PlaceRef { base: PlaceBase::Static(_), projection: [] } => {
bug!("qualifying already promoted MIR")
}
PlaceRef { base: _, projection: [.., _] } => Self::in_projection(cx, per_local, place),
}
}

View file

@ -369,15 +369,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
Rvalue::AddressOf(Mutability::Mut, _) => self.check_op(ops::MutAddressOf),
// At the moment, `PlaceBase::Static` is only used for promoted MIR.
Rvalue::Ref(_, BorrowKind::Shared, ref place)
| Rvalue::Ref(_, BorrowKind::Shallow, ref place)
| Rvalue::AddressOf(Mutability::Not, ref place)
if matches!(place.base, PlaceBase::Static(_)) =>
{
bug!("Saw a promoted during const-checking, which must run before promotion")
}
Rvalue::Ref(_, BorrowKind::Shared, ref place)
| Rvalue::Ref(_, BorrowKind::Shallow, ref place) => {
self.check_immutable_borrow_like(location, place)
@ -423,7 +414,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
fn visit_place_base(
&mut self,
place_base: &PlaceBase<'tcx>,
place_base: &PlaceBase,
context: PlaceContext,
location: Location,
) {
@ -437,9 +428,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
match place_base {
PlaceBase::Local(_) => {}
PlaceBase::Static(_) => {
bug!("Promotion must be run after const validation");
}
}
}
@ -453,7 +441,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
}
fn visit_projection_elem(
&mut self,
place_base: &PlaceBase<'tcx>,
place_base: &PlaceBase,
proj_base: &[PlaceElem<'tcx>],
elem: &PlaceElem<'tcx>,
context: PlaceContext,
@ -681,9 +669,11 @@ fn place_as_reborrow(
// A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const`
// that points to the allocation for the static. Don't treat these as reborrows.
if let PlaceBase::Local(local) = place.base {
if body.local_decls[local].is_ref_to_static() {
return None;
match place.base {
PlaceBase::Local(local) => {
if body.local_decls[local].is_ref_to_static() {
return None;
}
}
}

View file

@ -194,9 +194,6 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
PlaceBase::Local(..) => {
// Locals are safe.
}
PlaceBase::Static(box Static { .. }) => {
bug!("Static should not exist");
}
}
for (i, elem) in place.projection.iter().enumerate() {

View file

@ -872,8 +872,8 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
// doesn't use the invalid value
match cond {
Operand::Move(ref place) | Operand::Copy(ref place) => {
if let PlaceBase::Local(local) = place.base {
self.remove_const(local);
match place.base {
PlaceBase::Local(local) => self.remove_const(local),
}
}
Operand::Constant(_) => {}

View file

@ -275,18 +275,18 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
assert_eq!(self.remap.get(local), None);
}
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
if let PlaceBase::Local(l) = place.base {
fn visit_place(
&mut self,
place: &mut Place<'tcx>,
_context: PlaceContext,
_location: Location,
) {
match place.base {
PlaceBase::Local(l) =>
// Replace an Local in the remap with a generator struct access
if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) {
replace_base(place, self.make_field(variant_index, idx, ty), self.tcx);
}
} else {
self.visit_place_base(&mut place.base, context, location);
for elem in place.projection.iter() {
if let PlaceElem::Index(local) = elem {
assert_ne!(*local, self_arg());
{
if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) {
replace_base(place, self.make_field(variant_index, idx, ty), self.tcx);
}
}
}

View file

@ -431,9 +431,6 @@ impl Inliner<'tcx> {
}
match place.base {
// Static variables need a borrow because the callee
// might modify the same static.
PlaceBase::Static(_) => true,
_ => false,
}
}
@ -649,7 +646,6 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> {
if *local == RETURN_PLACE {
match self.destination.base {
PlaceBase::Local(l) => return l,
PlaceBase::Static(ref s) => bug!("Return place is {:?}, not local", s),
}
}
@ -673,7 +669,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
match &mut place.base {
PlaceBase::Static(_) => {}
PlaceBase::Local(l) => {
// If this is the `RETURN_PLACE`, we need to rebase any projections onto it.
let dest_proj_len = self.destination.projection.len();

View file

@ -310,7 +310,6 @@ impl<'tcx> Validator<'_, 'tcx> {
// don't get promoted anyway).
let base = match place.base {
PlaceBase::Local(local) => local,
_ => return Err(Unpromotable),
};
self.validate_local(base)?;
@ -482,9 +481,6 @@ impl<'tcx> Validator<'_, 'tcx> {
PlaceRef { base: PlaceBase::Local(local), projection: [] } => {
self.validate_local(*local)
}
PlaceRef { base: PlaceBase::Static(_), projection: [] } => {
bug!("qualifying already promoted MIR")
}
PlaceRef { base: _, projection: [proj_base @ .., elem] } => {
match *elem {
ProjectionElem::Deref | ProjectionElem::Downcast(..) => {
@ -648,7 +644,6 @@ impl<'tcx> Validator<'_, 'tcx> {
// `check_consts::qualifs` but without recursion.
let mut has_mut_interior = match place.base {
PlaceBase::Local(local) => self.qualif_local::<qualifs::HasMutInterior>(*local),
PlaceBase::Static(_) => false,
};
if has_mut_interior {
let mut place_projection = place.projection;

View file

@ -388,13 +388,9 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> {
// Remove unnecessary StorageLive and StorageDead annotations.
data.statements.retain(|stmt| match &stmt.kind {
StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => self.map[*l].is_some(),
StatementKind::Assign(box (place, _)) => {
if let PlaceBase::Local(local) = place.base {
self.map[local].is_some()
} else {
true
}
}
StatementKind::Assign(box (place, _)) => match place.base {
PlaceBase::Local(local) => self.map[local].is_some(),
},
_ => true,
});
self.super_basic_block_data(block, data);