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. /// changing or disturbing program state.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable)]
pub struct Place<'tcx> { pub struct Place<'tcx> {
pub base: PlaceBase<'tcx>, pub base: PlaceBase,
/// projection out of a place (access a field, deref a pointer, etc) /// projection out of a place (access a field, deref a pointer, etc)
pub projection: &'tcx List<PlaceElem<'tcx>>, pub projection: &'tcx List<PlaceElem<'tcx>>,
@ -1664,34 +1664,9 @@ pub struct Place<'tcx> {
impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {} impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)]
pub enum PlaceBase<'tcx> { pub enum PlaceBase {
/// local variable /// local variable
Local(Local), 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)] #[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)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PlaceRef<'a, 'tcx> { pub struct PlaceRef<'a, 'tcx> {
pub base: &'a PlaceBase<'tcx>, pub base: &'a PlaceBase,
pub projection: &'a [PlaceElem<'tcx>], 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 { fn from(local: Local) -> Self {
PlaceBase::Local(local) 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 { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
match *self { match *self {
PlaceBase::Local(id) => write!(fmt, "{:?}", id), 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 { fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
match self { match self {
PlaceBase::Local(local) => PlaceBase::Local(local.fold_with(folder)), 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 { fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match self { match self {
PlaceBase::Local(local) => local.visit_with(visitor), 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> { impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self { fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
use crate::mir::Rvalue::*; use crate::mir::Rvalue::*;

View file

@ -114,7 +114,7 @@ impl<'tcx> PlaceTy<'tcx> {
impl<'tcx> Place<'tcx> { impl<'tcx> Place<'tcx> {
pub fn ty_from<D>( pub fn ty_from<D>(
base: &PlaceBase<'tcx>, base: &PlaceBase,
projection: &[PlaceElem<'tcx>], projection: &[PlaceElem<'tcx>],
local_decls: &D, local_decls: &D,
tcx: TyCtxt<'tcx>, 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> pub fn ty<D>(&self, local_decls: &D) -> PlaceTy<'tcx>
where where
D: HasLocalDecls<'tcx>, D: HasLocalDecls<'tcx>,
{ {
match self { match self {
PlaceBase::Local(index) => PlaceTy::from_ty(local_decls.local_decls()[*index].ty), 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, fn visit_place_base(&mut self,
base: & $($mutability)? PlaceBase<'tcx>, base: & $($mutability)? PlaceBase,
context: PlaceContext, context: PlaceContext,
location: Location) { location: Location) {
self.super_place_base(base, context, location); self.super_place_base(base, context, location);
@ -705,16 +705,13 @@ macro_rules! make_mir_visitor {
} }
fn super_place_base(&mut self, fn super_place_base(&mut self,
place_base: & $($mutability)? PlaceBase<'tcx>, place_base: & $($mutability)? PlaceBase,
context: PlaceContext, context: PlaceContext,
location: Location) { location: Location) {
match place_base { match place_base {
PlaceBase::Local(local) => { PlaceBase::Local(local) => {
self.visit_local(local, context, location); 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( fn visit_projection(
&mut self, &mut self,
base: &PlaceBase<'tcx>, base: &PlaceBase,
projection: &[PlaceElem<'tcx>], projection: &[PlaceElem<'tcx>],
context: PlaceContext, context: PlaceContext,
location: Location, location: Location,
@ -899,7 +896,7 @@ macro_rules! visit_place_fns {
fn visit_projection_elem( fn visit_projection_elem(
&mut self, &mut self,
base: &PlaceBase<'tcx>, base: &PlaceBase,
proj_base: &[PlaceElem<'tcx>], proj_base: &[PlaceElem<'tcx>],
elem: &PlaceElem<'tcx>, elem: &PlaceElem<'tcx>,
context: PlaceContext, context: PlaceContext,
@ -934,7 +931,7 @@ macro_rules! visit_place_fns {
fn super_projection( fn super_projection(
&mut self, &mut self,
base: &PlaceBase<'tcx>, base: &PlaceBase,
projection: &[PlaceElem<'tcx>], projection: &[PlaceElem<'tcx>],
context: PlaceContext, context: PlaceContext,
location: Location, location: Location,
@ -948,7 +945,7 @@ macro_rules! visit_place_fns {
fn super_projection_elem( fn super_projection_elem(
&mut self, &mut self,
_base: &PlaceBase<'tcx>, _base: &PlaceBase,
_proj_base: &[PlaceElem<'tcx>], _proj_base: &[PlaceElem<'tcx>],
elem: &PlaceElem<'tcx>, elem: &PlaceElem<'tcx>,
_context: PlaceContext, _context: PlaceContext,

View file

@ -226,7 +226,7 @@ pub fn decode_place<D>(decoder: &mut D) -> Result<mir::Place<'tcx>, D::Error>
where where
D: TyDecoder<'tcx>, D: TyDecoder<'tcx>,
{ {
let base: mir::PlaceBase<'tcx> = Decodable::decode(decoder)?; let base: mir::PlaceBase = Decodable::decode(decoder)?;
let len = decoder.read_usize()?; let len = decoder.read_usize()?;
let projection: &'tcx List<mir::PlaceElem<'tcx>> = let projection: &'tcx List<mir::PlaceElem<'tcx>> =
decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?; 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_data_structures::graph::dominators::Dominators;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec}; use rustc_index::vec::{Idx, IndexVec};
use rustc_span::DUMMY_SP;
pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx: &FunctionCx<'a, 'tcx, Bx>, 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. // ZSTs don't require any actual memory access.
let elem_ty = base_ty.projection_ty(cx.tcx(), elem).ty; let elem_ty = base_ty.projection_ty(cx.tcx(), elem).ty;
let elem_ty = self.fx.monomorphize(&elem_ty); let elem_ty = self.fx.monomorphize(&elem_ty);
let span = if let mir::PlaceBase::Local(index) = place_ref.base { let span = match place_ref.base {
self.fx.mir.local_decls[*index].source_info.span mir::PlaceBase::Local(index) => {
} else { self.fx.mir.local_decls[*index].source_info.span
DUMMY_SP }
}; };
if cx.spanned_layout_of(elem_ty, span).is_zst() { if cx.spanned_layout_of(elem_ty, span).is_zst() {
return; return;
@ -179,8 +178,8 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
// We use `NonUseContext::VarDebugInfo` for the base, // We use `NonUseContext::VarDebugInfo` for the base,
// which might not force the base local to memory, // which might not force the base local to memory,
// so we have to do it manually. // so we have to do it manually.
if let mir::PlaceBase::Local(local) = place_ref.base { match place_ref.base {
self.visit_local(&local, context, location); 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() { if tcx.sess.opts.debuginfo == DebugInfo::Full || !tcx.sess.fewer_names() {
let mut per_local = IndexVec::from_elem(vec![], &body.local_decls); let mut per_local = IndexVec::from_elem(vec![], &body.local_decls);
for var in &body.var_debug_info { for var in &body.var_debug_info {
if let mir::PlaceBase::Local(local) = var.place.base { match var.place.base {
per_local[local].push(var); mir::PlaceBase::Local(local) => per_local[local].push(var),
} }
} }
Some(per_local) 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>> { ) -> Option<OperandRef<'tcx, Bx::Value>> {
debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref); debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref);
if let mir::PlaceBase::Local(index) = place_ref.base { match place_ref.base {
match self.locals[*index] { mir::PlaceBase::Local(index) => {
LocalRef::Operand(Some(mut o)) => { match self.locals[*index] {
// Moves out of scalar and scalar pair fields are trivial. LocalRef::Operand(Some(mut o)) => {
for elem in place_ref.projection.iter() { // Moves out of scalar and scalar pair fields are trivial.
match elem { for elem in place_ref.projection.iter() {
mir::ProjectionElem::Field(ref f, _) => { match elem {
o = o.extract_field(bx, f.index()); 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;
} }
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) Some(o)
} }
LocalRef::Operand(None) => { LocalRef::Operand(None) => {
bug!("use of {:?} before def", place_ref); bug!("use of {:?} before def", place_ref);
} }
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
// watch out for locals that do not have an // watch out for locals that do not have an
// alloca; they are handled somewhat differently // alloca; they are handled somewhat differently
None None
}
} }
} }
} else {
None
} }
} }

View file

@ -37,15 +37,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
PlaceRef { llval, llextra: None, layout, align } 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 // 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`). // unless LLVM IR names are turned on (e.g. for `--emit=llvm-ir`).
pub fn alloca<Bx: BuilderMethods<'a, 'tcx, Value = V>>( 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] } => { mir::PlaceRef { base, projection: [proj_base @ .., mir::ProjectionElem::Deref] } => {
// Load the pointer from its location. // Load the pointer from its location.
self.codegen_consume(bx, &mir::PlaceRef { base, projection: proj_base }) 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); self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx);
if let mir::PlaceBase::Local(local) = borrowed_place.base { match borrowed_place.base {
self.local_map.entry(local).or_default().insert(idx); 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: &[.., _] } => { PlaceRef { base: &PlaceBase::Local(local), projection: &[.., _] } => {
// Kill conflicting borrows of the innermost local. // Kill conflicting borrows of the innermost local.
debug!( debug!(

View file

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

View file

@ -2,7 +2,7 @@
use rustc::mir::{ use rustc::mir::{
AggregateKind, Constant, Field, Local, LocalInfo, LocalKind, Location, Operand, Place, 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, TerminatorKind,
}; };
use rustc::ty::layout::VariantIdx; use rustc::ty::layout::VariantIdx;
@ -172,9 +172,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
PlaceRef { base: PlaceBase::Local(local), projection: [] } => { PlaceRef { base: PlaceBase::Local(local), projection: [] } => {
self.append_local_to_string(*local, buf)?; 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] } PlaceRef { base: &PlaceBase::Local(local), projection: [ProjectionElem::Deref] }
if self.body.local_decls[local].is_ref_for_guard() => 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]; let local = &self.body.local_decls[*local];
self.describe_field_from_ty(&local.ty, field, None) 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 { PlaceRef { base, projection: [proj_base @ .., elem] } => match elem {
ProjectionElem::Deref => { ProjectionElem::Deref => {
self.describe_field(PlaceRef { base, projection: proj_base }, field) self.describe_field(PlaceRef { base, projection: proj_base }, field)

View file

@ -243,9 +243,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
); );
( (
match kind { match kind {
IllegalMoveOriginKind::Static => {
unreachable!();
}
IllegalMoveOriginKind::BorrowedContent { target_place } => self IllegalMoveOriginKind::BorrowedContent { target_place } => self
.report_cannot_move_from_borrowed_content( .report_cannot_move_from_borrowed_content(
original_path, 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::ConstantIndex { .. }] }
| PlaceRef { base: _, projection: [.., ProjectionElem::Subslice { .. }] } | PlaceRef { base: _, projection: [.., ProjectionElem::Subslice { .. }] }
| PlaceRef { base: _, projection: [.., ProjectionElem::Downcast(..)] } => { | 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::lint::builtin::UNUSED_MUT;
use rustc::mir::{ use rustc::mir::{
read_only, Body, BodyAndCache, ClearCrossCrate, Local, Location, Mutability, Operand, Place, 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::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
@ -815,7 +815,7 @@ enum InitializationRequiringAction {
} }
struct RootPlace<'d, 'tcx> { struct RootPlace<'d, 'tcx> {
place_base: &'d PlaceBase<'tcx>, place_base: &'d PlaceBase,
place_projection: &'d [PlaceElem<'tcx>], place_projection: &'d [PlaceElem<'tcx>],
is_local_mutation_allowed: LocalMutationIsAllowed, 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()) { if let Some(field) = this.is_upvar_field_projection(place.as_ref()) {
this.used_mut_upvars.push(field); this.used_mut_upvars.push(field);
} }
} else if let PlaceBase::Local(local) = place.base { } else {
this.used_mut.insert(local); 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? // FIXME: allow thread-locals to borrow other thread locals?
let (might_be_alive, will_be_dropped) = match root_place.base { let (might_be_alive, will_be_dropped) = match root_place.base {
PlaceBase::Static(_) => (true, false),
PlaceBase::Local(local) => { PlaceBase::Local(local) => {
if self.body.local_decls[*local].is_ref_to_thread_local() { if self.body.local_decls[*local].is_ref_to_thread_local() {
// Thread-locals might be dropped after the function exits // 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. // This code covers scenarios 1, 2, and 3.
debug!("check_if_full_path_is_moved place: {:?}", place_span.0); debug!("check_if_full_path_is_moved place: {:?}", place_span.0);
match self.move_path_closest_to(place_span.0) { let (prefix, mpi) = self.move_path_closest_to(place_span.0);
Ok((prefix, mpi)) => { if maybe_uninits.contains(mpi) {
if maybe_uninits.contains(mpi) { self.report_use_of_moved_or_uninitialized(
self.report_use_of_moved_or_uninitialized( location,
location, desired_action,
desired_action, (prefix, place_span.0, place_span.1),
(prefix, place_span.0, place_span.1), mpi,
mpi, );
); } // Only query longest prefix with a MovePath, not further
} // ancestors; dataflow recurs on children when parents
} // move (to support partial (re)inits).
Err(NoMovePathFound::ReachedStatic) => { //
// Okay: we do not build MoveData for static variables // (I.e., querying parents breaks scenario 7; but may want
} // Only query longest prefix with a MovePath, not further // to do such a query based on partial-init feature-gate.)
// 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 /// 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( fn move_path_closest_to(
&mut self, &mut self,
place: PlaceRef<'_, 'tcx>, place: PlaceRef<'_, 'tcx>,
) -> Result<(PlaceRef<'cx, 'tcx>, MovePathIndex), NoMovePathFound> { ) -> (PlaceRef<'cx, 'tcx>, MovePathIndex) {
match self.move_data.rev_lookup.find(place) { match self.move_data.rev_lookup.find(place) {
LookupResult::Parent(Some(mpi)) | LookupResult::Exact(mpi) => { 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, projection: proj_base,
}, span, flow_state); }, span, flow_state);
if let PlaceBase::Local(local) = place.base { match place.base {
// rust-lang/rust#21232, // rust-lang/rust#21232,
// #54499, #54986: during // #54499, #54986: during
// period where we reject // period where we reject
@ -1890,7 +1887,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// unnecessary `mut` on an // unnecessary `mut` on an
// attempt to do a partial // attempt to do a partial
// initialization. // 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 // partial initialization, do not complain about mutability
// errors except for actual mutation (as opposed to an attempt // errors except for actual mutation (as opposed to an attempt
// to do a partial initialization). // to do a partial initialization).
let previously_initialized = if let PlaceBase::Local(local) = place.base { let previously_initialized = match place.base {
self.is_local_ever_initialized(local, flow_state).is_some() PlaceBase::Local(local) => self.is_local_ever_initialized(local, flow_state).is_some(),
} else {
true
}; };
// at this point, we have set up the error reporting state. // 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); 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] } => { PlaceRef { base: _, projection: [proj_base @ .., elem] } => {
match elem { match elem {
ProjectionElem::Deref => { 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. /// The degree of overlap between 2 places for borrow-checking.
enum Overlap { enum Overlap {
/// The places might partially overlap - in this case, we give /// 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 /// This is called for all Yield expressions on movable generators
pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool { pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
match place.base { match place.base {
PlaceBase::Static(_) => false,
// Reborrow of already borrowed data is ignored // Reborrow of already borrowed data is ignored
// Any errors will be caught on the initial borrow // Any errors will be caught on the initial borrow
PlaceBase::Local(_) => !place.is_indirect(), 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() { 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 borrow_base = &borrow_place.base;
let access_base = access_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 => { Overlap::Arbitrary => {
bug!("Two base can't return 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 // Given that the bases of `elem1` and `elem2` are always either equal
// or disjoint (and have the same type!), return the overlap situation // or disjoint (and have the same type!), return the overlap situation
// between `elem1` and `elem2`. // between `elem1` and `elem2`.
fn place_base_conflict<'tcx>( fn place_base_conflict(elem1: &PlaceBase, elem2: &PlaceBase) -> Overlap {
tcx: TyCtxt<'tcx>,
elem1: &PlaceBase<'tcx>,
elem2: &PlaceBase<'tcx>,
) -> Overlap {
match (elem1, elem2) { match (elem1, elem2) {
(PlaceBase::Local(l1), PlaceBase::Local(l2)) => { (PlaceBase::Local(l1), PlaceBase::Local(l2)) => {
if l1 == l2 { if l1 == l2 {
@ -310,24 +306,6 @@ fn place_base_conflict<'tcx>(
Overlap::Disjoint 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>( fn place_projection_conflict<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
pi1_base: &PlaceBase<'tcx>, pi1_base: &PlaceBase,
pi1_proj_base: &[PlaceElem<'tcx>], pi1_proj_base: &[PlaceElem<'tcx>],
pi1_elem: &PlaceElem<'tcx>, pi1_elem: &PlaceElem<'tcx>,
pi2_elem: &PlaceElem<'tcx>, pi2_elem: &PlaceElem<'tcx>,

View file

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

View file

@ -467,32 +467,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
let mut place_ty = match &place.base { let mut place_ty = match &place.base {
PlaceBase::Local(index) => PlaceTy::from_ty(self.body.local_decls[*index].ty), 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() { 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 // 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 // they will either have been removed by unreachable code optimizations; or linted
// as unused variables. // as unused variables.
if let PlaceBase::Local(local) = into.base { match into.base {
let _ = self.never_initialized_mut_locals.remove(&local); 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) { fn visit_statement(&mut self, statement: &Statement<'tcx>, _location: Location) {
match &statement.kind { match &statement.kind {
StatementKind::Assign(box (into, _)) => { StatementKind::Assign(box (into, _)) => {
if let PlaceBase::Local(local) = into.base { match into.base {
debug!( PlaceBase::Local(local) => debug!(
"visit_statement: statement={:?} local={:?} \ "visit_statement: statement={:?} local={:?} \
never_initialized_mut_locals={:?}", never_initialized_mut_locals={:?}",
statement, local, self.never_initialized_mut_locals statement, local, self.never_initialized_mut_locals
); ),
} }
self.remove_never_initialized_mut_locals(into); 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`. /// and `c` can be progressively pushed onto the place builder that is created when converting `a`.
#[derive(Clone)] #[derive(Clone)]
struct PlaceBuilder<'tcx> { struct PlaceBuilder<'tcx> {
base: PlaceBase<'tcx>, base: PlaceBase,
projection: Vec<PlaceElem<'tcx>>, projection: Vec<PlaceElem<'tcx>>,
} }
@ -53,8 +53,8 @@ impl From<Local> for PlaceBuilder<'tcx> {
} }
} }
impl From<PlaceBase<'tcx>> for PlaceBuilder<'tcx> { impl From<PlaceBase> for PlaceBuilder<'tcx> {
fn from(base: PlaceBase<'tcx>) -> Self { fn from(base: PlaceBase) -> Self {
Self { base, projection: Vec::new() } 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>) { fn kill_borrows_on_place(&self, trans: &mut GenKillSet<BorrowIndex>, place: &Place<'tcx>) {
debug!("kill_borrows_on_place: place={:?}", place); debug!("kill_borrows_on_place: place={:?}", place);
if let PlaceBase::Local(local) = place.base { match place.base {
let other_borrows_of_local = PlaceBase::Local(local) => {
self.borrow_set.local_map.get(&local).into_iter().flat_map(|bs| bs.into_iter()); 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 // 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 // local must conflict. This is purely an optimization so we don't have to call
// `places_conflict` for every borrow. // `places_conflict` for every borrow.
if place.projection.is_empty() { if place.projection.is_empty() {
if !self.body.local_decls[local].is_ref_to_static() { if !self.body.local_decls[local].is_ref_to_static() {
trans.kill_all(other_borrows_of_local); 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 { match stmt.kind {
StatementKind::StorageDead(l) => sets.kill(l), StatementKind::StorageDead(l) => sets.kill(l),
StatementKind::Assign(box (ref place, _)) StatementKind::Assign(box (ref place, _))
| StatementKind::SetDiscriminant { box ref place, .. } => { | StatementKind::SetDiscriminant { box ref place, .. } => match place.base {
if let PlaceBase::Local(local) = place.base { PlaceBase::Local(local) => sets.gen(local),
sets.gen(local); },
}
}
StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => { StatementKind::InlineAsm(box InlineAsm { ref outputs, .. }) => {
for p in &**outputs { for p in &**outputs {
if let PlaceBase::Local(local) = p.base { match p.base {
sets.gen(local); PlaceBase::Local(local) => sets.gen(local),
} }
} }
} }
@ -171,8 +169,10 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
_dest_bb: mir::BasicBlock, _dest_bb: mir::BasicBlock,
dest_place: &mir::Place<'tcx>, dest_place: &mir::Place<'tcx>,
) { ) {
if let PlaceBase::Local(local) = dest_place.base { match dest_place.base {
in_out.insert(local); PlaceBase::Local(local) => {
in_out.insert(local);
}
} }
} }
} }

View file

@ -98,9 +98,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
debug!("lookup({:?})", place); debug!("lookup({:?})", place);
let mut base = match place.base { let mut base = match place.base {
PlaceBase::Local(local) => self.builder.data.rev_lookup.locals[local], 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 // 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 { pub fn find(&self, place: PlaceRef<'_, '_>) -> LookupResult {
let mut result = match place.base { let mut result = match place.base {
PlaceBase::Local(local) => self.locals[*local], PlaceBase::Local(local) => self.locals[*local],
PlaceBase::Static(..) => return LookupResult::Parent(None),
}; };
for elem in place.projection.iter() { for elem in place.projection.iter() {
@ -281,9 +280,6 @@ pub struct IllegalMoveOrigin<'tcx> {
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum IllegalMoveOriginKind<'tcx> { 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. /// Illegal move due to attempt to move from behind a reference.
BorrowedContent { BorrowedContent {
/// The place the reference refers to: if erroneous code was trying to /// 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)? self.access_local(self.frame(), *local, layout)?
} }
PlaceBase::Static(place_static) => self.eval_static_to_mplace(&place_static)?.into(),
}; };
let op = place let op = place

View file

@ -10,7 +10,6 @@ use rustc::mir::interpret::truncate;
use rustc::ty::layout::{ use rustc::ty::layout::{
self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx, self, Align, HasDataLayout, LayoutOf, PrimitiveExt, Size, TyLayout, VariantIdx,
}; };
use rustc::ty::TypeFoldable;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc_macros::HashStable; 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 /// 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`. /// place; for reading, a more efficient alternative is `eval_place_for_read`.
pub fn eval_place( pub fn eval_place(
@ -683,7 +653,6 @@ where
place: Place::Local { frame: self.cur_frame(), local: *local }, place: Place::Local { frame: self.cur_frame(), local: *local },
layout: self.layout_of_local(self.frame(), *local, None)?, 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() { 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::interpret::{ErrorHandled, GlobalAlloc, Scalar};
use rustc::mir::mono::{InstantiationMode, MonoItem}; use rustc::mir::mono::{InstantiationMode, MonoItem};
use rustc::mir::visit::Visitor as MirVisitor; 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::session::config::EntryFnType;
use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast};
use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::ty::print::obsolete::DefPathBasedNames;
@ -642,20 +642,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
fn visit_place_base( fn visit_place_base(
&mut self, &mut self,
place_base: &mir::PlaceBase<'tcx>, place_base: &mir::PlaceBase,
_context: mir::visit::PlaceContext, _context: mir::visit::PlaceContext,
location: Location, _location: Location,
) { ) {
match place_base { 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(_) => { PlaceBase::Local(_) => {
// Locals have no relevance for collector. // Locals have no relevance for collector.
} }

View file

@ -76,9 +76,6 @@ pub trait Qualif {
) -> bool { ) -> bool {
match place { match place {
PlaceRef { base: PlaceBase::Local(local), projection: [] } => per_local(*local), 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), 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), 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::Shared, ref place)
| Rvalue::Ref(_, BorrowKind::Shallow, ref place) => { | Rvalue::Ref(_, BorrowKind::Shallow, ref place) => {
self.check_immutable_borrow_like(location, place) self.check_immutable_borrow_like(location, place)
@ -423,7 +414,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
fn visit_place_base( fn visit_place_base(
&mut self, &mut self,
place_base: &PlaceBase<'tcx>, place_base: &PlaceBase,
context: PlaceContext, context: PlaceContext,
location: Location, location: Location,
) { ) {
@ -437,9 +428,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
match place_base { match place_base {
PlaceBase::Local(_) => {} 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( fn visit_projection_elem(
&mut self, &mut self,
place_base: &PlaceBase<'tcx>, place_base: &PlaceBase,
proj_base: &[PlaceElem<'tcx>], proj_base: &[PlaceElem<'tcx>],
elem: &PlaceElem<'tcx>, elem: &PlaceElem<'tcx>,
context: PlaceContext, 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` // 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. // that points to the allocation for the static. Don't treat these as reborrows.
if let PlaceBase::Local(local) = place.base { match place.base {
if body.local_decls[local].is_ref_to_static() { PlaceBase::Local(local) => {
return None; 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(..) => { PlaceBase::Local(..) => {
// Locals are safe. // Locals are safe.
} }
PlaceBase::Static(box Static { .. }) => {
bug!("Static should not exist");
}
} }
for (i, elem) in place.projection.iter().enumerate() { 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 // doesn't use the invalid value
match cond { match cond {
Operand::Move(ref place) | Operand::Copy(ref place) => { Operand::Move(ref place) | Operand::Copy(ref place) => {
if let PlaceBase::Local(local) = place.base { match place.base {
self.remove_const(local); PlaceBase::Local(local) => self.remove_const(local),
} }
} }
Operand::Constant(_) => {} Operand::Constant(_) => {}

View file

@ -275,18 +275,18 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
assert_eq!(self.remap.get(local), None); assert_eq!(self.remap.get(local), None);
} }
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { fn visit_place(
if let PlaceBase::Local(l) = place.base { &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 // 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); 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());
} }
} }
} }

View file

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

View file

@ -310,7 +310,6 @@ impl<'tcx> Validator<'_, 'tcx> {
// don't get promoted anyway). // don't get promoted anyway).
let base = match place.base { let base = match place.base {
PlaceBase::Local(local) => local, PlaceBase::Local(local) => local,
_ => return Err(Unpromotable),
}; };
self.validate_local(base)?; self.validate_local(base)?;
@ -482,9 +481,6 @@ impl<'tcx> Validator<'_, 'tcx> {
PlaceRef { base: PlaceBase::Local(local), projection: [] } => { PlaceRef { base: PlaceBase::Local(local), projection: [] } => {
self.validate_local(*local) self.validate_local(*local)
} }
PlaceRef { base: PlaceBase::Static(_), projection: [] } => {
bug!("qualifying already promoted MIR")
}
PlaceRef { base: _, projection: [proj_base @ .., elem] } => { PlaceRef { base: _, projection: [proj_base @ .., elem] } => {
match *elem { match *elem {
ProjectionElem::Deref | ProjectionElem::Downcast(..) => { ProjectionElem::Deref | ProjectionElem::Downcast(..) => {
@ -648,7 +644,6 @@ impl<'tcx> Validator<'_, 'tcx> {
// `check_consts::qualifs` but without recursion. // `check_consts::qualifs` but without recursion.
let mut has_mut_interior = match place.base { let mut has_mut_interior = match place.base {
PlaceBase::Local(local) => self.qualif_local::<qualifs::HasMutInterior>(*local), PlaceBase::Local(local) => self.qualif_local::<qualifs::HasMutInterior>(*local),
PlaceBase::Static(_) => false,
}; };
if has_mut_interior { if has_mut_interior {
let mut place_projection = place.projection; 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. // Remove unnecessary StorageLive and StorageDead annotations.
data.statements.retain(|stmt| match &stmt.kind { data.statements.retain(|stmt| match &stmt.kind {
StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => self.map[*l].is_some(), StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => self.map[*l].is_some(),
StatementKind::Assign(box (place, _)) => { StatementKind::Assign(box (place, _)) => match place.base {
if let PlaceBase::Local(local) = place.base { PlaceBase::Local(local) => self.map[local].is_some(),
self.map[local].is_some() },
} else {
true
}
}
_ => true, _ => true,
}); });
self.super_basic_block_data(block, data); self.super_basic_block_data(block, data);