1
Fork 0

Auto merge of #58103 - RalfJung:mir-shim-dump, r=eddyb

Make -Zdump-mir dump shims

Fixes https://github.com/rust-lang/rust/issues/53532 by (a) making the MIR shim generation use the MIR pass infrastructure, and (b) fixing said infrastructure to handle the fallout.

Cc @eddyb @oli-obk
This commit is contained in:
bors 2019-02-10 08:52:10 +00:00
commit de111e6367
28 changed files with 173 additions and 130 deletions

View file

@ -371,8 +371,12 @@ impl<'hir> Map<'hir> {
let def_id = self.local_def_id(variant.node.data.id());
Some(Def::Variant(def_id))
}
Node::Field(_) |
Node::StructCtor(variant) => {
let def_id = self.local_def_id(variant.id());
Some(Def::StructCtor(def_id, def::CtorKind::from_hir(variant)))
}
Node::AnonConst(_) |
Node::Field(_) |
Node::Expr(_) |
Node::Stmt(_) |
Node::PathSegment(_) |
@ -380,7 +384,6 @@ impl<'hir> Map<'hir> {
Node::TraitRef(_) |
Node::Pat(_) |
Node::Binding(_) |
Node::StructCtor(_) |
Node::Lifetime(_) |
Node::Visibility(_) |
Node::Block(_) |

View file

@ -209,7 +209,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
fn dump_mir_results<'a, 'gcx, 'tcx>(
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
source: MirSource,
source: MirSource<'tcx>,
mir: &Mir<'tcx>,
regioncx: &RegionInferenceContext<'_>,
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,

View file

@ -2427,8 +2427,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
pub struct TypeckMir;
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;
fn run_pass<'a, 'tcx>(
&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource<'tcx>,
mir: &mut Mir<'tcx>,
) {
let def_id = src.def_id();
debug!("run_pass: {:?}", def_id);
// When NLL is enabled, the borrow checker runs the typeck

View file

@ -16,8 +16,10 @@ use syntax_pos::Span;
use std::fmt;
use std::iter;
use crate::transform::{add_moves_for_packed_drops, add_call_guards};
use crate::transform::{remove_noop_landing_pads, no_landing_pads, simplify};
use crate::transform::{
add_moves_for_packed_drops, add_call_guards,
remove_noop_landing_pads, no_landing_pads, simplify, run_passes
};
use crate::util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode};
use crate::util::patch::MirPatch;
@ -113,12 +115,15 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
};
debug!("make_shim({:?}) = untransformed {:?}", instance, result);
add_moves_for_packed_drops::add_moves_for_packed_drops(
tcx, &mut result, instance.def_id());
no_landing_pads::no_landing_pads(tcx, &mut result);
remove_noop_landing_pads::remove_noop_landing_pads(tcx, &mut result);
simplify::simplify_cfg(&mut result);
add_call_guards::CriticalCallEdges.add_call_guards(&mut result);
run_passes(tcx, &mut result, instance, MirPhase::Const, &[
&add_moves_for_packed_drops::AddMovesForPackedDrops,
&no_landing_pads::NoLandingPads,
&remove_noop_landing_pads::RemoveNoopLandingPads,
&simplify::SimplifyCfg::new("make_shim"),
&add_call_guards::CriticalCallEdges,
]);
debug!("make_shim({:?}) = {:?}", instance, result);
tcx.alloc_mir(result)

View file

@ -33,7 +33,7 @@ pub use self::AddCallGuards::*;
impl MirPass for AddCallGuards {
fn run_pass<'a, 'tcx>(&self,
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource,
_src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
self.add_call_guards(mir);
}

View file

@ -42,11 +42,11 @@ pub struct AddMovesForPackedDrops;
impl MirPass for AddMovesForPackedDrops {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource,
src: MirSource<'tcx>,
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());
}
}

View file

@ -77,7 +77,7 @@ fn may_have_reference<'a, 'gcx, 'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>)
impl MirPass for AddRetag {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource,
_src: MirSource<'tcx>,
mir: &mut Mir<'tcx>)
{
if !tcx.sess.opts.debugging_opts.mir_emit_retag {

View file

@ -35,7 +35,7 @@ pub struct DeleteAscribeUserType;
impl MirPass for CleanAscribeUserType {
fn run_pass<'a, 'tcx>(&self,
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
_source: MirSource,
_source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
let mut delete = DeleteAscribeUserType;
delete.visit_mir(mir);
@ -69,7 +69,7 @@ pub struct DeleteFakeBorrows {
impl MirPass for CleanFakeReadsAndBorrows {
fn run_pass<'a, 'tcx>(&self,
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
_source: MirSource,
_source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
let mut delete_reads = DeleteAndRecordFakeReads::default();
delete_reads.visit_mir(mir);

View file

@ -30,7 +30,7 @@ pub struct ConstProp;
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() {
@ -38,11 +38,11 @@ impl MirPass for ConstProp {
}
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,
};
@ -50,11 +50,11 @@ impl MirPass for ConstProp {
// 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.
@ -63,7 +63,7 @@ impl MirPass for ConstProp {
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());
}
}
@ -74,7 +74,7 @@ struct ConstPropagator<'a, 'mir, 'tcx:'a+'mir> {
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>,
@ -107,10 +107,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, '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,
@ -284,13 +284,13 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
_ => 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),
@ -358,10 +358,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
)))
}
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) {
@ -398,10 +398,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, '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) {
@ -608,7 +608,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, '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 {

View file

@ -30,7 +30,7 @@ pub struct CopyPropagation;
impl MirPass for CopyPropagation {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_source: MirSource,
_source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
// We only run when the MIR optimization level is > 1.
// This avoids a slow pass, and messing up debug info.

View file

@ -8,7 +8,7 @@ pub struct Deaggregator;
impl MirPass for Deaggregator {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_source: MirSource,
_source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut();
let local_decls = &*local_decls;

View file

@ -20,7 +20,7 @@ impl MirPass for Marker {
fn run_pass<'a, 'tcx>(&self,
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
_source: MirSource,
_source: MirSource<'tcx>,
_mir: &mut Mir<'tcx>)
{
}
@ -41,7 +41,7 @@ impl fmt::Display for Disambiguator {
pub fn on_mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
pass_num: &dyn fmt::Display,
pass_name: &str,
source: MirSource,
source: MirSource<'tcx>,
mir: &Mir<'tcx>,
is_after: bool) {
if mir_util::dump_enabled(tcx, pass_name, source) {

View file

@ -23,13 +23,13 @@ pub struct ElaborateDrops;
impl MirPass for ElaborateDrops {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource,
src: MirSource<'tcx>,
mir: &mut Mir<'tcx>)
{
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)) => {

View file

@ -53,7 +53,7 @@ pub struct EraseRegions;
impl MirPass for EraseRegions {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_: MirSource,
_: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
EraseRegionsVisitor::new(tcx).visit_mir(mir);
}

View file

@ -376,14 +376,14 @@ impl<'tcx> Visitor<'tcx> for StorageIgnored {
fn locals_live_across_suspend_points(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
source: MirSource,
source: MirSource<'tcx>,
movable: bool,
) -> (
liveness::LiveVarSet<Local>,
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.
@ -484,7 +484,7 @@ fn locals_live_across_suspend_points(
}
fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource,
source: MirSource<'tcx>,
upvars: Vec<Ty<'tcx>>,
interior: Ty<'tcx>,
movable: bool,
@ -635,7 +635,7 @@ fn create_generator_drop_shim<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
transform: &TransformVisitor<'a, 'tcx>,
def_id: DefId,
source: MirSource,
source: MirSource<'tcx>,
gen_ty: Ty<'tcx>,
mir: &Mir<'tcx>,
drop_clean: BasicBlock) -> Mir<'tcx> {
@ -758,7 +758,7 @@ fn create_generator_resume_function<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
transform: TransformVisitor<'a, 'tcx>,
def_id: DefId,
source: MirSource,
source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
// Poison the generator when it unwinds
for block in mir.basic_blocks_mut() {
@ -869,7 +869,7 @@ fn create_cases<'a, 'tcx, F>(mir: &mut Mir<'tcx>,
impl MirPass for StateTransform {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource,
source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
let yield_ty = if let Some(yield_ty) = mir.yield_ty {
yield_ty
@ -880,7 +880,7 @@ impl MirPass for StateTransform {
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;

View file

@ -40,7 +40,7 @@ struct CallSite<'tcx> {
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);
@ -50,7 +50,7 @@ impl MirPass for Inline {
struct Inliner<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource,
source: MirSource<'tcx>,
}
impl<'a, 'tcx> Inliner<'a, 'tcx> {
@ -69,10 +69,10 @@ 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,
@ -274,7 +274,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
// 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;

View file

@ -13,7 +13,7 @@ pub struct InstCombine;
impl MirPass for InstCombine {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_: MirSource,
_: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
// We only run when optimizing MIR (at any level).
if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {

View file

@ -12,7 +12,7 @@ pub struct Lower128Bit;
impl MirPass for Lower128Bit {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource,
_src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops;
let target_default = tcx.sess.host.options.i128_lowering;

View file

@ -2,7 +2,7 @@ use crate::borrow_check::nll::type_check;
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;
@ -104,20 +104,25 @@ fn mir_built<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea
/// 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
@ -141,14 +146,14 @@ pub trait MirPass {
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],
) {
@ -160,7 +165,7 @@ pub fn run_passes(
}
let source = MirSource {
def_id,
instance,
promoted,
};
let mut index = 0;
@ -198,7 +203,7 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea
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,
@ -217,7 +222,7 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
}
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"),
@ -235,7 +240,7 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
}
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"),

View file

@ -11,7 +11,7 @@ pub struct NoLandingPads;
impl MirPass for NoLandingPads {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_: MirSource,
_: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
no_landing_pads(tcx, mir)
}

View file

@ -1159,7 +1159,7 @@ pub struct QualifyAndPromoteConstants;
impl MirPass for QualifyAndPromoteConstants {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource,
src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
// There's not really any point in promoting errorful MIR.
if mir.return_ty().references_error() {
@ -1171,7 +1171,7 @@ impl MirPass for QualifyAndPromoteConstants {
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) {

View file

@ -24,7 +24,7 @@ pub fn remove_noop_landing_pads<'a, 'tcx>(
impl MirPass for RemoveNoopLandingPads {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource,
_src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
remove_noop_landing_pads(tcx, mir);
}

View file

@ -24,8 +24,8 @@ pub struct SanityCheck;
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;
src: MirSource<'tcx>, mir: &mut Mir<'tcx>) {
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));

View file

@ -59,7 +59,7 @@ impl MirPass for SimplifyCfg {
fn run_pass<'a, 'tcx>(&self,
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource,
_src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
simplify_cfg(mir);
@ -298,7 +298,7 @@ pub struct SimplifyLocals;
impl MirPass for SimplifyLocals {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_: MirSource,
_: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
let mut marker = DeclMarker { locals: BitSet::new_empty(mir.local_decls.len()) };
marker.visit_mir(mir);

View file

@ -21,7 +21,7 @@ impl MirPass for SimplifyBranches {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource,
_src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
for block in mir.basic_blocks_mut() {
let terminator = block.terminator_mut();

View file

@ -39,7 +39,7 @@ pub struct UniformArrayMoveOut;
impl MirPass for UniformArrayMoveOut {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource,
_src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
let mut patch = MirPatch::new(mir);
{
@ -161,7 +161,7 @@ pub struct RestoreSubsliceArrayMoveOut;
impl MirPass for RestoreSubsliceArrayMoveOut {
fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource,
_src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) {
let mut patch = MirPatch::new(mir);
{

View file

@ -307,7 +307,7 @@ fn block<'tcx, V: Idx>(
pub fn dump_mir<'a, 'tcx, V: Idx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
pass_name: &str,
source: MirSource,
source: MirSource<'tcx>,
mir: &Mir<'tcx>,
map: &impl LiveVariableMap<LiveVar = V>,
result: &LivenessResult<V>,
@ -317,7 +317,7 @@ pub fn dump_mir<'a, 'tcx, V: Idx>(
}
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);
}
@ -326,14 +326,14 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
pass_name: &str,
node_path: &str,
source: MirSource,
source: MirSource<'tcx>,
mir: &Mir<'tcx>,
map: &dyn LiveVariableMap<LiveVar = V>,
result: &LivenessResult<V>,
) {
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| {
@ -348,7 +348,7 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
pub fn write_mir_fn<'a, 'tcx, V: Idx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource,
src: MirSource<'tcx>,
mir: &Mir<'tcx>,
map: &dyn LiveVariableMap<LiveVar = V>,
w: &mut dyn Write,

View file

@ -1,4 +1,3 @@
use rustc::hir;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::mir::*;
use rustc::mir::visit::Visitor;
@ -69,7 +68,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
pass_num: Option<&dyn Display>,
pass_name: &str,
disambiguator: &dyn Display,
source: MirSource,
source: MirSource<'tcx>,
mir: &Mir<'tcx>,
extra_data: F,
) where
@ -81,7 +80,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
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,
@ -98,7 +97,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
pub fn dump_enabled<'a, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
pass_name: &str,
source: MirSource,
source: MirSource<'tcx>,
) -> bool {
let filters = match tcx.sess.opts.debugging_opts.dump_mir {
None => return false,
@ -106,7 +105,7 @@ pub fn dump_enabled<'a, 'gcx, '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| {
@ -125,7 +124,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
pass_name: &str,
node_path: &str,
disambiguator: &dyn Display,
source: MirSource,
source: MirSource<'tcx>,
mir: &Mir<'tcx>,
mut extra_data: F,
) where
@ -151,7 +150,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
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)?;
};
}
}
@ -165,7 +164,7 @@ fn dump_path(
pass_num: Option<&dyn Display>,
pass_name: &str,
disambiguator: &dyn Display,
source: MirSource,
source: MirSource<'tcx>,
) -> PathBuf {
let promotion_id = match source.promoted {
Some(id) => format!("-{:?}", id),
@ -184,13 +183,32 @@ fn dump_path(
let mut file_path = PathBuf::new();
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
let item_name = tcx.hir()
.def_path(source.def_id)
let item_name = tcx
.def_path(source.def_id())
.to_filename_friendly_no_crate();
// All drop shims have the same DefId, so we have to add the type
// to get unique file names.
let shim_disambiguator = match source.instance {
ty::InstanceDef::DropGlue(_, Some(ty)) => {
// Unfortunately, pretty-printed typed are not very filename-friendly.
// We dome some filtering.
let mut s = ".".to_owned();
s.extend(ty.to_string()
.chars()
.filter_map(|c| match c {
' ' => None,
':' => Some('_'),
c => Some(c)
}));
s
}
_ => String::new(),
};
let file_name = format!(
"rustc.{}{}{}.{}.{}.{}",
"rustc.{}{}{}{}.{}.{}.{}",
item_name,
shim_disambiguator,
promotion_id,
pass_num,
pass_name,
@ -213,7 +231,7 @@ pub(crate) fn create_dump_file(
pass_num: Option<&dyn Display>,
pass_name: &str,
disambiguator: &dyn Display,
source: MirSource,
source: MirSource<'tcx>,
) -> io::Result<fs::File> {
let file_path = dump_path(tcx, extension, pass_num, pass_name, disambiguator, source);
if let Some(parent) = file_path.parent() {
@ -253,7 +271,7 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>(
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)?;
@ -264,7 +282,7 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>(
pub fn write_mir_fn<'a, 'gcx, 'tcx, F>(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
src: MirSource,
src: MirSource<'tcx>,
mir: &Mir<'tcx>,
extra_data: &mut F,
w: &mut dyn Write,
@ -528,7 +546,7 @@ fn write_scope_tree(
/// local variables (both user-defined bindings and compiler temporaries).
pub fn write_mir_intro<'a, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>,
src: MirSource,
src: MirSource<'tcx>,
mir: &Mir<'_>,
w: &mut dyn Write,
) -> io::Result<()> {
@ -570,45 +588,49 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>(
fn write_mir_sig(
tcx: TyCtxt<'_, '_, '_>,
src: MirSource,
src: MirSource<'tcx>,
mir: &Mir<'_>,
w: &mut dyn Write,
) -> io::Result<()> {
let id = tcx.hir().as_local_node_id(src.def_id).unwrap();
let body_owner_kind = tcx.hir().body_owner_kind(id);
match (body_owner_kind, src.promoted) {
(_, Some(i)) => write!(w, "{:?} in", i)?,
(hir::BodyOwnerKind::Closure, _) |
(hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?,
(hir::BodyOwnerKind::Const, _) => write!(w, "const")?,
(hir::BodyOwnerKind::Static(hir::MutImmutable), _) => write!(w, "static")?,
(hir::BodyOwnerKind::Static(hir::MutMutable), _) => write!(w, "static mut")?,
use rustc::hir::def::Def;
trace!("write_mir_sig: {:?}", src.instance);
let descr = tcx.describe_def(src.def_id());
let is_function = match descr {
Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true,
_ => tcx.is_closure(src.def_id()),
};
match (descr, src.promoted) {
(_, Some(i)) => write!(w, "{:?} in ", i)?,
(Some(Def::StructCtor(..)), _) => write!(w, "struct ")?,
(Some(Def::Const(_)), _) => write!(w, "const ")?,
(Some(Def::Static(_, /*is_mutbl*/false)), _) => write!(w, "static ")?,
(Some(Def::Static(_, /*is_mutbl*/true)), _) => write!(w, "static mut ")?,
(_, _) if is_function => write!(w, "fn ")?,
(None, _) => {}, // things like anon const, not an item
_ => bug!("Unexpected def description {:?}", descr),
}
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 (body_owner_kind, src.promoted) {
(hir::BodyOwnerKind::Closure, None) |
(hir::BodyOwnerKind::Fn, None) => {
write!(w, "(")?;
if src.promoted.is_none() && is_function {
write!(w, "(")?;
// fn argument types.
for (i, arg) in mir.args_iter().enumerate() {
if i != 0 {
write!(w, ", ")?;
}
write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?;
// fn argument types.
for (i, arg) in mir.args_iter().enumerate() {
if i != 0 {
write!(w, ", ")?;
}
write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?;
}
write!(w, ") -> {}", mir.return_ty())?;
}
(hir::BodyOwnerKind::Const, _) | (hir::BodyOwnerKind::Static(_), _) | (_, Some(_)) => {
assert_eq!(mir.arg_count, 0);
write!(w, ": {} =", mir.return_ty())?;
}
write!(w, ") -> {}", mir.return_ty())?;
} else {
assert_eq!(mir.arg_count, 0);
write!(w, ": {} =", mir.return_ty())?;
}
if let Some(yield_ty) = mir.yield_ty {
@ -616,6 +638,9 @@ fn write_mir_sig(
writeln!(w, "yields {}", yield_ty)?;
}
write!(w, " ")?;
// Next thing that gets printed is the opening {
Ok(())
}