impl MirPass for TypeckMir {
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) {
- let def_id = src.def_id;
+ let def_id = src.def_id();
debug!("run_pass: {:?}", def_id);
// When NLL is enabled, the borrow checker runs the typeck
};
debug!("make_shim({:?}) = untransformed {:?}", instance, result);
- run_passes(tcx, &mut result, instance.def_id(), MirPhase::Const, &[
+ run_passes(tcx, &mut result, instance, MirPhase::Const, &[
&add_moves_for_packed_drops::AddMovesForPackedDrops,
&no_landing_pads::NoLandingPads,
&remove_noop_landing_pads::RemoveNoopLandingPads,
mir: &mut Mir<'tcx>)
{
debug!("add_moves_for_packed_drops({:?} @ {:?})", src, mir.span);
- add_moves_for_packed_drops(tcx, mir, src.def_id);
+ add_moves_for_packed_drops(tcx, mir, src.def_id());
}
}
impl MirPass for ConstProp {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- source: MirSource,
+ source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
// will be evaluated by miri and produce its errors there
if source.promoted.is_some() {
}
use rustc::hir::map::blocks::FnLikeNode;
- let node_id = tcx.hir().as_local_node_id(source.def_id)
+ let node_id = tcx.hir().as_local_node_id(source.def_id())
.expect("Non-local call to local provider is_const_fn");
let is_fn_like = FnLikeNode::from_node(tcx.hir().get(node_id)).is_some();
- let is_assoc_const = match tcx.describe_def(source.def_id) {
+ let is_assoc_const = match tcx.describe_def(source.def_id()) {
Some(Def::AssociatedConst(_)) => true,
_ => false,
};
// Only run const prop on functions, methods, closures and associated constants
if !is_fn_like && !is_assoc_const {
// skip anon_const/statics/consts because they'll be evaluated by miri anyway
- trace!("ConstProp skipped for {:?}", source.def_id);
+ trace!("ConstProp skipped for {:?}", source.def_id());
return
}
- trace!("ConstProp starting for {:?}", source.def_id);
+ trace!("ConstProp starting for {:?}", source.def_id());
// FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
// constants, instead of just checking for const-folding succeeding.
let mut optimization_finder = ConstPropagator::new(mir, tcx, source);
optimization_finder.visit_mir(mir);
- trace!("ConstProp done for {:?}", source.def_id);
+ trace!("ConstProp done for {:?}", source.def_id());
}
}
ecx: EvalContext<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>>,
mir: &'mir Mir<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- source: MirSource,
+ source: MirSource<'tcx>,
places: IndexVec<Local, Option<Const<'tcx>>>,
can_const_prop: IndexVec<Local, bool>,
param_env: ParamEnv<'tcx>,
fn new(
mir: &'mir Mir<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- source: MirSource,
+ source: MirSource<'tcx>,
) -> ConstPropagator<'a, 'mir, 'tcx> {
- let param_env = tcx.param_env(source.def_id);
- let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id), param_env);
+ let param_env = tcx.param_env(source.def_id());
+ let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id()), param_env);
ConstPropagator {
ecx,
mir,
_ => None,
},
Place::Promoted(ref promoted) => {
- let generics = self.tcx.generics_of(self.source.def_id);
+ let generics = self.tcx.generics_of(self.source.def_id());
if generics.requires_monomorphization(self.tcx) {
// FIXME: can't handle code with generics
return None;
}
- let substs = Substs::identity_for_item(self.tcx, self.source.def_id);
- let instance = Instance::new(self.source.def_id, substs);
+ let substs = Substs::identity_for_item(self.tcx, self.source.def_id());
+ let instance = Instance::new(self.source.def_id(), substs);
let cid = GlobalId {
instance,
promoted: Some(promoted.0),
)))
}
Rvalue::UnaryOp(op, ref arg) => {
- let def_id = if self.tcx.is_closure(self.source.def_id) {
- self.tcx.closure_base_def_id(self.source.def_id)
+ let def_id = if self.tcx.is_closure(self.source.def_id()) {
+ self.tcx.closure_base_def_id(self.source.def_id())
} else {
- self.source.def_id
+ self.source.def_id()
};
let generics = self.tcx.generics_of(def_id);
if generics.requires_monomorphization(self.tcx) {
Rvalue::BinaryOp(op, ref left, ref right) => {
trace!("rvalue binop {:?} for {:?} and {:?}", op, left, right);
let right = self.eval_operand(right, source_info)?;
- let def_id = if self.tcx.is_closure(self.source.def_id) {
- self.tcx.closure_base_def_id(self.source.def_id)
+ let def_id = if self.tcx.is_closure(self.source.def_id()) {
+ self.tcx.closure_base_def_id(self.source.def_id())
} else {
- self.source.def_id
+ self.source.def_id()
};
let generics = self.tcx.generics_of(def_id);
if generics.requires_monomorphization(self.tcx) {
let node_id = self
.tcx
.hir()
- .as_local_node_id(self.source.def_id)
+ .as_local_node_id(self.source.def_id())
.expect("some part of a failing const eval must be local");
use rustc::mir::interpret::EvalErrorKind::*;
let msg = match msg {
{
debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
- let id = tcx.hir().as_local_node_id(src.def_id).unwrap();
- let param_env = tcx.param_env(src.def_id).with_reveal_all();
+ let id = tcx.hir().as_local_node_id(src.def_id()).unwrap();
+ let param_env = tcx.param_env(src.def_id()).with_reveal_all();
let move_data = match MoveData::gather_moves(mir, tcx) {
Ok(move_data) => move_data,
Err((move_data, _move_errors)) => {
FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>,
) {
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
- let node_id = tcx.hir().as_local_node_id(source.def_id).unwrap();
+ let node_id = tcx.hir().as_local_node_id(source.def_id()).unwrap();
// Calculate when MIR locals have live storage. This gives us an upper bound of their
// lifetimes.
assert!(mir.generator_drop.is_none());
- let def_id = source.def_id;
+ let def_id = source.def_id();
// The first argument is the generator type passed by value
let gen_ty = mir.local_decls.raw[1].ty;
impl MirPass for Inline {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- source: MirSource,
+ source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
Inliner { tcx, source }.run_pass(mir);
struct Inliner<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- source: MirSource,
+ source: MirSource<'tcx>,
}
impl<'a, 'tcx> Inliner<'a, 'tcx> {
let mut callsites = VecDeque::new();
- let param_env = self.tcx.param_env(self.source.def_id);
+ let param_env = self.tcx.param_env(self.source.def_id());
// Only do inlining into fn bodies.
- let id = self.tcx.hir().as_local_node_id(self.source.def_id).unwrap();
+ let id = self.tcx.hir().as_local_node_id(self.source.def_id()).unwrap();
if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() && self.source.promoted.is_none() {
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
if let Some(callsite) = self.get_valid_function_call(bb,
// FIXME: Give a bonus to functions with only a single caller
- let param_env = tcx.param_env(self.source.def_id);
+ let param_env = tcx.param_env(self.source.def_id());
let mut first_block = true;
let mut cost = 0;
use crate::build;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::mir::{Mir, MirPhase, Promoted};
-use rustc::ty::TyCtxt;
+use rustc::ty::{TyCtxt, InstanceDef};
use rustc::ty::query::Providers;
use rustc::ty::steal::Steal;
use rustc::hir;
/// Where a specific Mir comes from.
#[derive(Debug, Copy, Clone)]
-pub struct MirSource {
- pub def_id: DefId,
+pub struct MirSource<'tcx> {
+ pub instance: InstanceDef<'tcx>,
/// If `Some`, this is a promoted rvalue within the parent function.
pub promoted: Option<Promoted>,
}
-impl MirSource {
+impl<'tcx> MirSource<'tcx> {
pub fn item(def_id: DefId) -> Self {
MirSource {
- def_id,
+ instance: InstanceDef::Item(def_id),
promoted: None
}
}
+
+ #[inline]
+ pub fn def_id(&self) -> DefId {
+ self.instance.def_id()
+ }
}
/// Generates a default name for the pass based on the name of the
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
- source: MirSource,
+ source: MirSource<'tcx>,
mir: &mut Mir<'tcx>);
}
pub fn run_passes(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &mut Mir<'tcx>,
- def_id: DefId,
+ instance: InstanceDef<'tcx>,
mir_phase: MirPhase,
passes: &[&dyn MirPass],
) {
}
let source = MirSource {
- def_id,
+ instance,
promoted,
};
let mut index = 0;
let _ = tcx.unsafety_check_result(def_id);
let mut mir = tcx.mir_built(def_id).steal();
- run_passes(tcx, &mut mir, def_id, MirPhase::Const, &[
+ run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Const, &[
// What we need to do constant evaluation.
&simplify::SimplifyCfg::new("initial"),
&type_check::TypeckMir,
}
let mut mir = tcx.mir_const(def_id).steal();
- run_passes(tcx, &mut mir, def_id, MirPhase::Validated, &[
+ run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Validated, &[
// What we need to run borrowck etc.
&qualify_consts::QualifyAndPromoteConstants,
&simplify::SimplifyCfg::new("qualify-consts"),
}
let mut mir = tcx.mir_validated(def_id).steal();
- run_passes(tcx, &mut mir, def_id, MirPhase::Optimized, &[
+ run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Optimized, &[
// Remove all things not needed by analysis
&no_landing_pads::NoLandingPads,
&simplify_branches::SimplifyBranches::new("initial"),
return;
}
- let def_id = src.def_id;
+ let def_id = src.def_id();
let id = tcx.hir().as_local_node_id(def_id).unwrap();
let mut const_promoted_temps = None;
let mode = match tcx.hir().body_owner_kind(id) {
impl MirPass for SanityCheck {
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource, mir: &mut Mir<'tcx>) {
- let def_id = src.def_id;
+ let def_id = src.def_id();
let id = tcx.hir().as_local_node_id(def_id).unwrap();
if !tcx.has_attr(def_id, "rustc_mir") {
debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
}
let node_path = item_path::with_forced_impl_filename_line(|| {
// see notes on #41697 below
- tcx.item_path_str(source.def_id)
+ tcx.item_path_str(source.def_id())
});
dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, map, result);
}
) {
let mut file_path = PathBuf::new();
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
- let item_id = tcx.hir().as_local_node_id(source.def_id).unwrap();
+ let item_id = tcx.hir().as_local_node_id(source.def_id()).unwrap();
let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name);
file_path.push(&file_name);
let _ = fs::File::create(&file_path).and_then(|mut file| {
let node_path = item_path::with_forced_impl_filename_line(|| {
// see notes on #41697 below
- tcx.item_path_str(source.def_id)
+ tcx.item_path_str(source.def_id())
});
dump_matched_mir_node(
tcx,
};
let node_path = item_path::with_forced_impl_filename_line(|| {
// see notes on #41697 below
- tcx.item_path_str(source.def_id)
+ tcx.item_path_str(source.def_id())
});
filters.split('|').any(|or_filter| {
or_filter.split('&').all(|and_filter| {
let _: io::Result<()> = try {
let mut file =
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
- write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?;
+ write_mir_fn_graphviz(tcx, source.def_id(), mir, &mut file)?;
};
}
}
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
let item_name = tcx
- .def_path(source.def_id)
+ .def_path(source.def_id())
.to_filename_friendly_no_crate();
let file_name = format!(
for (i, mir) in mir.promoted.iter_enumerated() {
writeln!(w, "")?;
let src = MirSource {
- def_id,
+ instance: ty::InstanceDef::Item(def_id),
promoted: Some(i),
};
write_mir_fn(tcx, src, mir, &mut |_, _| Ok(()), w)?;
) -> io::Result<()> {
use rustc::hir::def::Def;
- debug!("write_mir_sig: {:?} {:?}", src.def_id, tcx.hir().get_if_local(src.def_id));
- let descr = tcx.describe_def(src.def_id).unwrap();
+ trace!("write_mir_sig: {:?} {:?}", src, tcx.hir().get_if_local(src.def_id()));
+ let descr = tcx.describe_def(src.def_id()).unwrap();
match (descr, src.promoted) {
(_, Some(i)) => write!(w, "{:?} in", i)?,
(Def::Fn(_), _) | (Def::Method(_), _) => write!(w, "fn")?,
item_path::with_forced_impl_filename_line(|| {
// see notes on #41697 elsewhere
- write!(w, " {}", tcx.item_path_str(src.def_id))
+ write!(w, " {}", tcx.item_path_str(src.def_id()))
})?;
match (descr, src.promoted) {