Remove Static from PlaceBase
This commit is contained in:
parent
9e70c47783
commit
fd5aa32c35
37 changed files with 192 additions and 451 deletions
|
@ -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::*;
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)))?;
|
||||
|
|
|
@ -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 {
|
||||
let span = match place_ref.base {
|
||||
mir::PlaceBase::Local(index) => {
|
||||
self.fx.mir.local_decls[*index].source_info.span
|
||||
} else {
|
||||
DUMMY_SP
|
||||
}
|
||||
};
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -373,7 +373,8 @@ 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 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.
|
||||
|
@ -409,8 +410,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 })
|
||||
|
|
|
@ -208,10 +208,12 @@ 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 {
|
||||
match borrowed_place.base {
|
||||
mir::PlaceBase::Local(local) => {
|
||||
self.local_map.entry(local).or_default().insert(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.super_assign(assigned_place, rvalue, location)
|
||||
}
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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,13 +708,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
borrow_span,
|
||||
));
|
||||
|
||||
if let PlaceBase::Local(local) = borrow.borrowed_place.base {
|
||||
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);
|
||||
let err = self.report_thread_local_value_does_not_live_long_enough(
|
||||
drop_span,
|
||||
borrow_span,
|
||||
);
|
||||
err.buffer(&mut self.errors_buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let StorageDeadOrDrop::Destructor(dropped_ty) =
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(..)] } => {
|
||||
|
|
|
@ -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,9 +1251,13 @@ 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 {
|
||||
} else {
|
||||
match place.base {
|
||||
PlaceBase::Local(local) => {
|
||||
this.used_mut.insert(local);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// This relies on the current way that by-value
|
||||
|
@ -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,8 +1652,7 @@ 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)) => {
|
||||
let (prefix, mpi) = self.move_path_closest_to(place_span.0);
|
||||
if maybe_uninits.contains(mpi) {
|
||||
self.report_use_of_moved_or_uninitialized(
|
||||
location,
|
||||
|
@ -1658,10 +1660,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
(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).
|
||||
|
@ -1669,7 +1667,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
// (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
|
||||
/// elements of the base array. For each element we check
|
||||
|
@ -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,9 +1887,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
// unnecessary `mut` on an
|
||||
// attempt to do a partial
|
||||
// initialization.
|
||||
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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -47,7 +47,6 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
|
|||
}
|
||||
}
|
||||
},
|
||||
PlaceBase::Static(_) => return true,
|
||||
};
|
||||
|
||||
for (i, elem) in self.projection.iter().enumerate() {
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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={:?}",
|
||||
statement, local, self.never_initialized_mut_locals
|
||||
);
|
||||
),
|
||||
}
|
||||
self.remove_never_initialized_mut_locals(into);
|
||||
}
|
||||
|
|
|
@ -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() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,7 +195,8 @@ 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 {
|
||||
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());
|
||||
|
||||
|
@ -227,6 +228,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'tcx> {
|
||||
type Idx = BorrowIndex;
|
||||
|
|
|
@ -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,11 +169,13 @@ 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 {
|
||||
match dest_place.base {
|
||||
PlaceBase::Local(local) => {
|
||||
in_out.insert(local);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> {
|
||||
/// Kill locals that are fully moved and have not been borrowed.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,11 +669,13 @@ 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 {
|
||||
match place.base {
|
||||
PlaceBase::Local(local) => {
|
||||
if body.local_decls[local].is_ref_to_static() {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the type being derefed is a reference and not a raw pointer.
|
||||
//
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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(_) => {}
|
||||
|
|
|
@ -275,19 +275,19 @@ 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue