Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Promoted and Static in mir::Place #59232

Merged
merged 8 commits into from
Mar 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 29 additions & 21 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1913,22 +1913,24 @@ pub enum PlaceBase<'tcx> {

/// static or static mut variable
Static(Box<Static<'tcx>>),

/// Constant code promoted to an injected static
Promoted(Box<(Promoted, Ty<'tcx>)>),
}

/// The `DefId` of a static, along with its normalized type (which is
/// stored to avoid requiring normalization when reading MIR).
/// We store the normalized type to avoid requiring normalization when reading MIR
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct Static<'tcx> {
pub def_id: DefId,
pub ty: Ty<'tcx>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @arielb1 @nikomatsakis Are pre-normalized types in MIR still needed?

pub kind: StaticKind,
}

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable)]
pub enum StaticKind {
Promoted(Promoted),
Static(DefId),
}

impl_stable_hash_for!(struct Static<'tcx> {
def_id,
ty
ty,
kind
});

/// The `Projection` data structure defines things of the form `B.x`
Expand Down Expand Up @@ -2048,7 +2050,7 @@ impl<'tcx> Place<'tcx> {
match self {
Place::Base(PlaceBase::Local(local)) => Some(*local),
Place::Projection(box Projection { base, elem: _ }) => base.base_local(),
Place::Base(PlaceBase::Promoted(..)) | Place::Base(PlaceBase::Static(..)) => None,
Place::Base(PlaceBase::Static(..)) => None,
}
}
}
Expand All @@ -2059,18 +2061,24 @@ impl<'tcx> Debug for Place<'tcx> {

match *self {
Base(PlaceBase::Local(id)) => write!(fmt, "{:?}", id),
Base(PlaceBase::Static(box self::Static { def_id, ty })) => write!(
fmt,
"({}: {:?})",
ty::tls::with(|tcx| tcx.def_path_str(def_id)),
ty
),
Base(PlaceBase::Promoted(ref promoted)) => write!(
fmt,
"({:?}: {:?})",
promoted.0,
promoted.1
),
Base(PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static(def_id) })) => {
write!(
fmt,
"({}: {:?})",
ty::tls::with(|tcx| tcx.def_path_str(def_id)),
ty
)
},
Base(PlaceBase::Static(
box self::Static { ty, kind: StaticKind::Promoted(promoted) })
) => {
write!(
fmt,
"({:?}: {:?})",
promoted,
ty
)
},
Projection(ref data) => match data.elem {
ProjectionElem::Downcast(ref adt_def, index) => {
write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].ident)
Expand Down
1 change: 0 additions & 1 deletion src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ impl<'tcx> Place<'tcx> {
match *self {
Place::Base(PlaceBase::Local(index)) =>
PlaceTy::Ty { ty: local_decls.local_decls()[index].ty },
Place::Base(PlaceBase::Promoted(ref data)) => PlaceTy::Ty { ty: data.1 },
Place::Base(PlaceBase::Static(ref data)) =>
PlaceTy::Ty { ty: data.ty },
Place::Projection(ref proj) =>
Expand Down
26 changes: 5 additions & 21 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,6 @@ macro_rules! make_mir_visitor {
self.super_place(place, context, location);
}

fn visit_static(&mut self,
static_: & $($mutability)? Static<'tcx>,
context: PlaceContext<'tcx>,
location: Location) {
self.super_static(static_, context, location);
}

fn visit_projection(&mut self,
place: & $($mutability)? PlaceProjection<'tcx>,
context: PlaceContext<'tcx>,
Expand Down Expand Up @@ -736,27 +729,18 @@ macro_rules! make_mir_visitor {
Place::Base(PlaceBase::Local(local)) => {
self.visit_local(local, context, location);
}
Place::Base(PlaceBase::Static(static_)) => {
self.visit_static(static_, context, location);
Place::Base(PlaceBase::Static(box Static { kind, ty })) => {
if let StaticKind::Static(def_id) = kind {
self.visit_def_id(& $($mutability)? *def_id, location)
}
self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
}
Place::Base(PlaceBase::Promoted(promoted)) => {
self.visit_ty(& $($mutability)? promoted.1, TyContext::Location(location));
},
Place::Projection(proj) => {
self.visit_projection(proj, context, location);
}
}
}

fn super_static(&mut self,
static_: & $($mutability)? Static<'tcx>,
_context: PlaceContext<'tcx>,
location: Location) {
let Static { def_id, ty } = static_;
self.visit_def_id(def_id, location);
self.visit_ty(ty, TyContext::Location(location));
}

fn super_projection(&mut self,
proj: & $($mutability)? PlaceProjection<'tcx>,
context: PlaceContext<'tcx>,
Expand Down
16 changes: 12 additions & 4 deletions src/librustc_codegen_ssa/mir/block.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rustc::middle::lang_items;
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
use rustc::mir;
use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
use rustc::mir::interpret::EvalErrorKind;
use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode};
use rustc_target::spec::abi::Abi;
Expand Down Expand Up @@ -621,15 +621,23 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// but specified directly in the code. This means it gets promoted
// and we can then extract the value by evaluating the promoted.
mir::Operand::Copy(
mir::Place::Base(mir::PlaceBase::Promoted(box(index, ty)))
Place::Base(
PlaceBase::Static(
box Static { kind: StaticKind::Promoted(promoted), ty }
)
)
) |
mir::Operand::Move(
mir::Place::Base(mir::PlaceBase::Promoted(box(index, ty)))
Place::Base(
PlaceBase::Static(
box Static { kind: StaticKind::Promoted(promoted), ty }
)
)
) => {
let param_env = ty::ParamEnv::reveal_all();
let cid = mir::interpret::GlobalId {
instance: self.instance,
promoted: Some(index),
promoted: Some(promoted),
};
let c = bx.tcx().const_eval(param_env.and(cid));
let (llval, ty) = self.simd_shuffle_indices(
Expand Down
14 changes: 11 additions & 3 deletions src/librustc_codegen_ssa/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,11 +408,15 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

let result = match *place {
mir::Place::Base(mir::PlaceBase::Local(_)) => bug!(), // handled above
mir::Place::Base(mir::PlaceBase::Promoted(box (index, ty))) => {
mir::Place::Base(
mir::PlaceBase::Static(
box mir::Static { ty, kind: mir::StaticKind::Promoted(promoted) }
)
) => {
let param_env = ty::ParamEnv::reveal_all();
let cid = mir::interpret::GlobalId {
instance: self.instance,
promoted: Some(index),
promoted: Some(promoted),
};
let layout = cx.layout_of(self.monomorphize(&ty));
match bx.tcx().const_eval(param_env.and(cid)) {
Expand All @@ -435,7 +439,11 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
mir::Place::Base(mir::PlaceBase::Static(box mir::Static { def_id, ty })) => {
mir::Place::Base(
mir::PlaceBase::Static(
box mir::Static { ty, kind: mir::StaticKind::Static(def_id) }
)
) => {
// 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));
Expand Down
23 changes: 11 additions & 12 deletions src/librustc_mir/borrow_check/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc::mir::{
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, Constant,
ConstraintCategory, Field, Local, LocalDecl, LocalKind, Location, Operand,
Place, PlaceBase, PlaceProjection, ProjectionElem, Rvalue, Statement, StatementKind,
TerminatorKind, VarBindingForm,
Static, StaticKind, TerminatorKind, VarBindingForm,
};
use rustc::ty::{self, DefIdTree};
use rustc::ty::print::Print;
Expand Down Expand Up @@ -1598,14 +1598,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
including_downcast: &IncludingDowncast,
) -> Result<(), ()> {
match *place {
Place::Base(PlaceBase::Promoted(_)) => {
buf.push_str("promoted");
}
Place::Base(PlaceBase::Local(local)) => {
self.append_local_to_string(local, buf)?;
}
Place::Base(PlaceBase::Static(ref static_)) => {
buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string());
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {
buf.push_str("promoted");
}
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
buf.push_str(&self.infcx.tcx.item_name(def_id).to_string());
}
Place::Projection(ref proj) => {
match proj.elem {
Expand Down Expand Up @@ -1744,8 +1744,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let local = &self.mir.local_decls[local];
self.describe_field_from_ty(&local.ty, field)
}
Place::Base(PlaceBase::Promoted(ref prom)) =>
self.describe_field_from_ty(&prom.1, field),
Place::Base(PlaceBase::Static(ref static_)) =>
self.describe_field_from_ty(&static_.ty, field),
Place::Projection(ref proj) => match proj.elem {
Expand Down Expand Up @@ -1809,8 +1807,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {

/// Checks if a place is a thread-local static.
pub fn is_place_thread_local(&self, place: &Place<'tcx>) -> bool {
if let Place::Base(PlaceBase::Static(statik)) = place {
let attrs = self.infcx.tcx.get_attrs(statik.def_id);
if let Place::Base(
PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })
) = place {
let attrs = self.infcx.tcx.get_attrs(*def_id);
let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local"));

debug!(
Expand All @@ -1828,8 +1828,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let tcx = self.infcx.tcx;
match place {
Place::Base(PlaceBase::Local(_)) |
Place::Base(PlaceBase::Static(_)) |
Place::Base(PlaceBase::Promoted(_)) => {
Place::Base(PlaceBase::Static(_)) => {
StorageDeadOrDrop::LocalStorageDead
}
Place::Projection(box PlaceProjection { base, elem }) => {
Expand Down
34 changes: 15 additions & 19 deletions src/librustc_mir/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use rustc::infer::InferCtxt;
use rustc::lint::builtin::UNUSED_MUT;
use rustc::middle::borrowck::SignalledError;
use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place, PlaceBase};
use rustc::mir::{
ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place, PlaceBase, Static, StaticKind
};
use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind};
use rustc::ty::query::Providers;
Expand Down Expand Up @@ -1226,8 +1228,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
}
Operand::Move(Place::Base(PlaceBase::Static(..)))
| Operand::Copy(Place::Base(PlaceBase::Static(..)))
| Operand::Move(Place::Base(PlaceBase::Promoted(..)))
| Operand::Copy(Place::Base(PlaceBase::Promoted(..)))
| Operand::Constant(..) => {}
}
}
Expand Down Expand Up @@ -1310,12 +1310,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
//
// FIXME: allow thread-locals to borrow other thread locals?
let (might_be_alive, will_be_dropped) = match root_place {
Place::Base(PlaceBase::Promoted(_)) => (true, false),
Place::Base(PlaceBase::Static(_)) => {
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {
(true, false)
}
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(_), .. })) => {
// Thread-locals might be dropped after the function exits, but
// "true" statics will never be.
let is_thread_local = self.is_place_thread_local(&root_place);
(true, is_thread_local)
(true, self.is_place_thread_local(&root_place))
}
Place::Base(PlaceBase::Local(_)) => {
// Locals are always dropped at function exit, and if they
Expand Down Expand Up @@ -1578,7 +1579,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
match *last_prefix {
Place::Base(PlaceBase::Local(_)) => panic!("should have move path for every Local"),
Place::Projection(_) => panic!("PrefixSet::All meant don't stop for Projection"),
Place::Base(PlaceBase::Promoted(_)) |
Place::Base(PlaceBase::Static(_)) => Err(NoMovePathFound::ReachedStatic),
}
}
Expand All @@ -1605,7 +1605,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let mut place = place;
loop {
match *place {
Place::Base(PlaceBase::Promoted(_)) |
Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => {
// assigning to `x` does not require `x` be initialized.
break;
Expand Down Expand Up @@ -1953,10 +1952,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
self.used_mut_upvars.push(field);
}
}
RootPlace {
place: Place::Base(PlaceBase::Promoted(..)),
is_local_mutation_allowed: _,
} => {}
RootPlace {
place: Place::Base(PlaceBase::Static(..)),
is_local_mutation_allowed: _,
Expand Down Expand Up @@ -1994,12 +1989,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
}
// The rules for promotion are made by `qualify_consts`, there wouldn't even be a
// `Place::Promoted` if the promotion weren't 100% legal. So we just forward this
Place::Base(PlaceBase::Promoted(_)) => Ok(RootPlace {
place,
is_local_mutation_allowed,
}),
Place::Base(PlaceBase::Static(ref static_)) => {
if self.infcx.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) {
Place::Base(PlaceBase::Static(box Static{kind: StaticKind::Promoted(_), ..})) =>
Ok(RootPlace {
place,
is_local_mutation_allowed,
}),
Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
if self.infcx.tcx.is_static(def_id) != Some(hir::Mutability::MutMutable) {
Err(place)
} else {
Ok(RootPlace {
Expand Down
9 changes: 6 additions & 3 deletions src/librustc_mir/borrow_check/mutability_errors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use rustc::hir;
use rustc::hir::Node;
use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Mir};
use rustc::mir::{Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static};
use rustc::mir::{
Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind,
};
use rustc::mir::{Terminator, TerminatorKind};
use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt};
use rustc_data_structures::indexed_vec::Idx;
Expand Down Expand Up @@ -129,9 +131,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
}
}

Place::Base(PlaceBase::Promoted(_)) => unreachable!(),
Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) =>
unreachable!(),

Place::Base(PlaceBase::Static(box Static { def_id, ty: _ })) => {
Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. })) => {
if let Place::Base(PlaceBase::Static(_)) = access_place {
item_msg = format!("immutable static item `{}`", access_place_desc.unwrap());
reason = String::new();
Expand Down
Loading