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.
|
/// 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::*;
|
||||||
|
|
|
@ -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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)))?;
|
||||||
|
|
|
@ -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 {
|
||||||
|
mir::PlaceBase::Local(index) => {
|
||||||
self.fx.mir.local_decls[*index].source_info.span
|
self.fx.mir.local_decls[*index].source_info.span
|
||||||
} else {
|
}
|
||||||
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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -373,7 +373,8 @@ 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 {
|
||||||
|
mir::PlaceBase::Local(index) => {
|
||||||
match self.locals[*index] {
|
match self.locals[*index] {
|
||||||
LocalRef::Operand(Some(mut o)) => {
|
LocalRef::Operand(Some(mut o)) => {
|
||||||
// Moves out of scalar and scalar pair fields are trivial.
|
// 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
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 })
|
||||||
|
|
|
@ -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);
|
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.local_map.entry(local).or_default().insert(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.super_assign(assigned_place, rvalue, location)
|
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: &[.., _] } => {
|
PlaceRef { base: &PlaceBase::Local(local), projection: &[.., _] } => {
|
||||||
// Kill conflicting borrows of the innermost local.
|
// Kill conflicting borrows of the innermost local.
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
@ -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,13 +708,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
borrow_span,
|
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() {
|
if self.body.local_decls[local].is_ref_to_thread_local() {
|
||||||
let err = self
|
let err = self.report_thread_local_value_does_not_live_long_enough(
|
||||||
.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span);
|
drop_span,
|
||||||
|
borrow_span,
|
||||||
|
);
|
||||||
err.buffer(&mut self.errors_buffer);
|
err.buffer(&mut self.errors_buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let StorageDeadOrDrop::Destructor(dropped_ty) =
|
if let StorageDeadOrDrop::Destructor(dropped_ty) =
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(..)] } => {
|
||||||
|
|
|
@ -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,9 +1251,13 @@ 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 {
|
||||||
|
match place.base {
|
||||||
|
PlaceBase::Local(local) => {
|
||||||
this.used_mut.insert(local);
|
this.used_mut.insert(local);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This relies on the current way that by-value
|
// 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?
|
// 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,8 +1652,7 @@ 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,
|
||||||
|
@ -1658,10 +1660,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
(prefix, place_span.0, place_span.1),
|
(prefix, place_span.0, place_span.1),
|
||||||
mpi,
|
mpi,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(NoMovePathFound::ReachedStatic) => {
|
|
||||||
// Okay: we do not build MoveData for static variables
|
|
||||||
} // Only query longest prefix with a MovePath, not further
|
} // Only query longest prefix with a MovePath, not further
|
||||||
// ancestors; dataflow recurs on children when parents
|
// ancestors; dataflow recurs on children when parents
|
||||||
// move (to support partial (re)inits).
|
// 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
|
// (I.e., querying parents breaks scenario 7; but may want
|
||||||
// to do such a query based on partial-init feature-gate.)
|
// 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
|
||||||
/// elements of the base array. For each element we check
|
/// 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(
|
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,9 +1887,11 @@ 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.
|
||||||
|
PlaceBase::Local(local) => {
|
||||||
self.used_mut.insert(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
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,8 @@ 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 {
|
||||||
|
PlaceBase::Local(local) => {
|
||||||
let other_borrows_of_local =
|
let other_borrows_of_local =
|
||||||
self.borrow_set.local_map.get(&local).into_iter().flat_map(|bs| bs.into_iter());
|
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> {
|
impl<'a, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'tcx> {
|
||||||
type Idx = BorrowIndex;
|
type Idx = BorrowIndex;
|
||||||
|
|
|
@ -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,11 +169,13 @@ 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 {
|
||||||
|
PlaceBase::Local(local) => {
|
||||||
in_out.insert(local);
|
in_out.insert(local);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> {
|
impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> {
|
||||||
/// Kill locals that are fully moved and have not been borrowed.
|
/// 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);
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,11 +669,13 @@ 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 {
|
||||||
|
PlaceBase::Local(local) => {
|
||||||
if body.local_decls[local].is_ref_to_static() {
|
if body.local_decls[local].is_ref_to_static() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure the type being derefed is a reference and not a raw pointer.
|
// 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(..) => {
|
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() {
|
||||||
|
|
|
@ -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(_) => {}
|
||||||
|
|
|
@ -275,19 +275,19 @@ 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) {
|
if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) {
|
||||||
replace_base(place, self.make_field(variant_index, idx, ty), self.tcx);
|
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 {
|
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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue