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()); let def_id = self.local_def_id(variant.node.data.id());
Some(Def::Variant(def_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::AnonConst(_) |
Node::Field(_) |
Node::Expr(_) | Node::Expr(_) |
Node::Stmt(_) | Node::Stmt(_) |
Node::PathSegment(_) | Node::PathSegment(_) |
@ -380,7 +384,6 @@ impl<'hir> Map<'hir> {
Node::TraitRef(_) | Node::TraitRef(_) |
Node::Pat(_) | Node::Pat(_) |
Node::Binding(_) | Node::Binding(_) |
Node::StructCtor(_) |
Node::Lifetime(_) | Node::Lifetime(_) |
Node::Visibility(_) | Node::Visibility(_) |
Node::Block(_) | 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>( fn dump_mir_results<'a, 'gcx, 'tcx>(
infcx: &InferCtxt<'a, 'gcx, 'tcx>, infcx: &InferCtxt<'a, 'gcx, 'tcx>,
source: MirSource, source: MirSource<'tcx>,
mir: &Mir<'tcx>, mir: &Mir<'tcx>,
regioncx: &RegionInferenceContext<'_>, regioncx: &RegionInferenceContext<'_>,
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>, closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,

View file

@ -2427,8 +2427,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
pub struct TypeckMir; pub struct TypeckMir;
impl MirPass for TypeckMir { impl MirPass for TypeckMir {
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { fn run_pass<'a, 'tcx>(
let def_id = src.def_id; &self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource<'tcx>,
mir: &mut Mir<'tcx>,
) {
let def_id = src.def_id();
debug!("run_pass: {:?}", def_id); debug!("run_pass: {:?}", def_id);
// When NLL is enabled, the borrow checker runs the typeck // 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::fmt;
use std::iter; use std::iter;
use crate::transform::{add_moves_for_packed_drops, add_call_guards}; use crate::transform::{
use crate::transform::{remove_noop_landing_pads, no_landing_pads, simplify}; 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::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode};
use crate::util::patch::MirPatch; 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); debug!("make_shim({:?}) = untransformed {:?}", instance, result);
add_moves_for_packed_drops::add_moves_for_packed_drops(
tcx, &mut result, instance.def_id()); run_passes(tcx, &mut result, instance, MirPhase::Const, &[
no_landing_pads::no_landing_pads(tcx, &mut result); &add_moves_for_packed_drops::AddMovesForPackedDrops,
remove_noop_landing_pads::remove_noop_landing_pads(tcx, &mut result); &no_landing_pads::NoLandingPads,
simplify::simplify_cfg(&mut result); &remove_noop_landing_pads::RemoveNoopLandingPads,
add_call_guards::CriticalCallEdges.add_call_guards(&mut result); &simplify::SimplifyCfg::new("make_shim"),
&add_call_guards::CriticalCallEdges,
]);
debug!("make_shim({:?}) = {:?}", instance, result); debug!("make_shim({:?}) = {:?}", instance, result);
tcx.alloc_mir(result) tcx.alloc_mir(result)

View file

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

View file

@ -42,11 +42,11 @@ pub struct AddMovesForPackedDrops;
impl MirPass for AddMovesForPackedDrops { impl MirPass for AddMovesForPackedDrops {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource, src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) mir: &mut Mir<'tcx>)
{ {
debug!("add_moves_for_packed_drops({:?} @ {:?})", src, mir.span); 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 { impl MirPass for AddRetag {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource, _src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) mir: &mut Mir<'tcx>)
{ {
if !tcx.sess.opts.debugging_opts.mir_emit_retag { if !tcx.sess.opts.debugging_opts.mir_emit_retag {

View file

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

View file

@ -30,7 +30,7 @@ pub struct ConstProp;
impl MirPass for ConstProp { impl MirPass for ConstProp {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource, source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
// will be evaluated by miri and produce its errors there // will be evaluated by miri and produce its errors there
if source.promoted.is_some() { if source.promoted.is_some() {
@ -38,11 +38,11 @@ impl MirPass for ConstProp {
} }
use rustc::hir::map::blocks::FnLikeNode; 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"); .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_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, Some(Def::AssociatedConst(_)) => true,
_ => false, _ => false,
}; };
@ -50,11 +50,11 @@ impl MirPass for ConstProp {
// Only run const prop on functions, methods, closures and associated constants // Only run const prop on functions, methods, closures and associated constants
if !is_fn_like && !is_assoc_const { if !is_fn_like && !is_assoc_const {
// skip anon_const/statics/consts because they'll be evaluated by miri anyway // 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 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 // FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
// constants, instead of just checking for const-folding succeeding. // 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); let mut optimization_finder = ConstPropagator::new(mir, tcx, source);
optimization_finder.visit_mir(mir); 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>>, ecx: EvalContext<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>>,
mir: &'mir Mir<'tcx>, mir: &'mir Mir<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource, source: MirSource<'tcx>,
places: IndexVec<Local, Option<Const<'tcx>>>, places: IndexVec<Local, Option<Const<'tcx>>>,
can_const_prop: IndexVec<Local, bool>, can_const_prop: IndexVec<Local, bool>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
@ -107,10 +107,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
fn new( fn new(
mir: &'mir Mir<'tcx>, mir: &'mir Mir<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource, source: MirSource<'tcx>,
) -> ConstPropagator<'a, 'mir, 'tcx> { ) -> ConstPropagator<'a, 'mir, 'tcx> {
let param_env = tcx.param_env(source.def_id); let param_env = tcx.param_env(source.def_id());
let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id), param_env); let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id()), param_env);
ConstPropagator { ConstPropagator {
ecx, ecx,
mir, mir,
@ -284,13 +284,13 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
_ => None, _ => None,
}, },
Place::Promoted(ref promoted) => { 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) { if generics.requires_monomorphization(self.tcx) {
// FIXME: can't handle code with generics // FIXME: can't handle code with generics
return None; return None;
} }
let substs = Substs::identity_for_item(self.tcx, self.source.def_id); let substs = Substs::identity_for_item(self.tcx, self.source.def_id());
let instance = Instance::new(self.source.def_id, substs); let instance = Instance::new(self.source.def_id(), substs);
let cid = GlobalId { let cid = GlobalId {
instance, instance,
promoted: Some(promoted.0), promoted: Some(promoted.0),
@ -358,10 +358,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
))) )))
} }
Rvalue::UnaryOp(op, ref arg) => { Rvalue::UnaryOp(op, ref arg) => {
let def_id = if self.tcx.is_closure(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) self.tcx.closure_base_def_id(self.source.def_id())
} else { } else {
self.source.def_id self.source.def_id()
}; };
let generics = self.tcx.generics_of(def_id); let generics = self.tcx.generics_of(def_id);
if generics.requires_monomorphization(self.tcx) { 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) => { Rvalue::BinaryOp(op, ref left, ref right) => {
trace!("rvalue binop {:?} for {:?} and {:?}", op, left, right); trace!("rvalue binop {:?} for {:?} and {:?}", op, left, right);
let right = self.eval_operand(right, source_info)?; let right = self.eval_operand(right, source_info)?;
let def_id = if self.tcx.is_closure(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) self.tcx.closure_base_def_id(self.source.def_id())
} else { } else {
self.source.def_id self.source.def_id()
}; };
let generics = self.tcx.generics_of(def_id); let generics = self.tcx.generics_of(def_id);
if generics.requires_monomorphization(self.tcx) { 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 let node_id = self
.tcx .tcx
.hir() .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"); .expect("some part of a failing const eval must be local");
use rustc::mir::interpret::EvalErrorKind::*; use rustc::mir::interpret::EvalErrorKind::*;
let msg = match msg { let msg = match msg {

View file

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

View file

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

View file

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

View file

@ -23,13 +23,13 @@ pub struct ElaborateDrops;
impl MirPass for ElaborateDrops { impl MirPass for ElaborateDrops {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource, src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) mir: &mut Mir<'tcx>)
{ {
debug!("elaborate_drops({:?} @ {:?})", src, mir.span); debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
let id = tcx.hir().as_local_node_id(src.def_id).unwrap(); 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 param_env = tcx.param_env(src.def_id()).with_reveal_all();
let move_data = match MoveData::gather_moves(mir, tcx) { let move_data = match MoveData::gather_moves(mir, tcx) {
Ok(move_data) => move_data, Ok(move_data) => move_data,
Err((move_data, _move_errors)) => { Err((move_data, _move_errors)) => {

View file

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

View file

@ -376,14 +376,14 @@ impl<'tcx> Visitor<'tcx> for StorageIgnored {
fn locals_live_across_suspend_points( fn locals_live_across_suspend_points(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>, mir: &Mir<'tcx>,
source: MirSource, source: MirSource<'tcx>,
movable: bool, movable: bool,
) -> ( ) -> (
liveness::LiveVarSet<Local>, liveness::LiveVarSet<Local>,
FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>, FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>,
) { ) {
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len()); 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 // Calculate when MIR locals have live storage. This gives us an upper bound of their
// lifetimes. // lifetimes.
@ -484,7 +484,7 @@ fn locals_live_across_suspend_points(
} }
fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource, source: MirSource<'tcx>,
upvars: Vec<Ty<'tcx>>, upvars: Vec<Ty<'tcx>>,
interior: Ty<'tcx>, interior: Ty<'tcx>,
movable: bool, movable: bool,
@ -635,7 +635,7 @@ fn create_generator_drop_shim<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
transform: &TransformVisitor<'a, 'tcx>, transform: &TransformVisitor<'a, 'tcx>,
def_id: DefId, def_id: DefId,
source: MirSource, source: MirSource<'tcx>,
gen_ty: Ty<'tcx>, gen_ty: Ty<'tcx>,
mir: &Mir<'tcx>, mir: &Mir<'tcx>,
drop_clean: BasicBlock) -> Mir<'tcx> { drop_clean: BasicBlock) -> Mir<'tcx> {
@ -758,7 +758,7 @@ fn create_generator_resume_function<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
transform: TransformVisitor<'a, 'tcx>, transform: TransformVisitor<'a, 'tcx>,
def_id: DefId, def_id: DefId,
source: MirSource, source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
// Poison the generator when it unwinds // Poison the generator when it unwinds
for block in mir.basic_blocks_mut() { 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 { impl MirPass for StateTransform {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource, source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
let yield_ty = if let Some(yield_ty) = mir.yield_ty { let yield_ty = if let Some(yield_ty) = mir.yield_ty {
yield_ty yield_ty
@ -880,7 +880,7 @@ impl MirPass for StateTransform {
assert!(mir.generator_drop.is_none()); 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 // The first argument is the generator type passed by value
let gen_ty = mir.local_decls.raw[1].ty; let gen_ty = mir.local_decls.raw[1].ty;

View file

@ -40,7 +40,7 @@ struct CallSite<'tcx> {
impl MirPass for Inline { impl MirPass for Inline {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource, source: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
Inliner { tcx, source }.run_pass(mir); Inliner { tcx, source }.run_pass(mir);
@ -50,7 +50,7 @@ impl MirPass for Inline {
struct Inliner<'a, 'tcx: 'a> { struct Inliner<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource, source: MirSource<'tcx>,
} }
impl<'a, 'tcx> Inliner<'a, 'tcx> { impl<'a, 'tcx> Inliner<'a, 'tcx> {
@ -69,10 +69,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
let mut callsites = VecDeque::new(); 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. // 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() { 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() { for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
if let Some(callsite) = self.get_valid_function_call(bb, 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 // 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 first_block = true;
let mut cost = 0; let mut cost = 0;

View file

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

View file

@ -12,7 +12,7 @@ pub struct Lower128Bit;
impl MirPass for Lower128Bit { impl MirPass for Lower128Bit {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource, _src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops; let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops;
let target_default = tcx.sess.host.options.i128_lowering; 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 crate::build;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::mir::{Mir, MirPhase, Promoted}; use rustc::mir::{Mir, MirPhase, Promoted};
use rustc::ty::TyCtxt; use rustc::ty::{TyCtxt, InstanceDef};
use rustc::ty::query::Providers; use rustc::ty::query::Providers;
use rustc::ty::steal::Steal; use rustc::ty::steal::Steal;
use rustc::hir; 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. /// Where a specific Mir comes from.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MirSource { pub struct MirSource<'tcx> {
pub def_id: DefId, pub instance: InstanceDef<'tcx>,
/// If `Some`, this is a promoted rvalue within the parent function. /// If `Some`, this is a promoted rvalue within the parent function.
pub promoted: Option<Promoted>, pub promoted: Option<Promoted>,
} }
impl MirSource { impl<'tcx> MirSource<'tcx> {
pub fn item(def_id: DefId) -> Self { pub fn item(def_id: DefId) -> Self {
MirSource { MirSource {
def_id, instance: InstanceDef::Item(def_id),
promoted: None 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 /// 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, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource, source: MirSource<'tcx>,
mir: &mut Mir<'tcx>); mir: &mut Mir<'tcx>);
} }
pub fn run_passes( pub fn run_passes(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &mut Mir<'tcx>, mir: &mut Mir<'tcx>,
def_id: DefId, instance: InstanceDef<'tcx>,
mir_phase: MirPhase, mir_phase: MirPhase,
passes: &[&dyn MirPass], passes: &[&dyn MirPass],
) { ) {
@ -160,7 +165,7 @@ pub fn run_passes(
} }
let source = MirSource { let source = MirSource {
def_id, instance,
promoted, promoted,
}; };
let mut index = 0; 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 _ = tcx.unsafety_check_result(def_id);
let mut mir = tcx.mir_built(def_id).steal(); 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. // What we need to do constant evaluation.
&simplify::SimplifyCfg::new("initial"), &simplify::SimplifyCfg::new("initial"),
&type_check::TypeckMir, &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(); 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. // What we need to run borrowck etc.
&qualify_consts::QualifyAndPromoteConstants, &qualify_consts::QualifyAndPromoteConstants,
&simplify::SimplifyCfg::new("qualify-consts"), &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(); 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 // Remove all things not needed by analysis
&no_landing_pads::NoLandingPads, &no_landing_pads::NoLandingPads,
&simplify_branches::SimplifyBranches::new("initial"), &simplify_branches::SimplifyBranches::new("initial"),

View file

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

View file

@ -1159,7 +1159,7 @@ pub struct QualifyAndPromoteConstants;
impl MirPass for QualifyAndPromoteConstants { impl MirPass for QualifyAndPromoteConstants {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource, src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
// There's not really any point in promoting errorful MIR. // There's not really any point in promoting errorful MIR.
if mir.return_ty().references_error() { if mir.return_ty().references_error() {
@ -1171,7 +1171,7 @@ impl MirPass for QualifyAndPromoteConstants {
return; 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 id = tcx.hir().as_local_node_id(def_id).unwrap();
let mut const_promoted_temps = None; let mut const_promoted_temps = None;
let mode = match tcx.hir().body_owner_kind(id) { 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 { impl MirPass for RemoveNoopLandingPads {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource, _src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
remove_noop_landing_pads(tcx, mir); remove_noop_landing_pads(tcx, mir);
} }

View file

@ -24,8 +24,8 @@ pub struct SanityCheck;
impl MirPass for SanityCheck { impl MirPass for SanityCheck {
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource, mir: &mut Mir<'tcx>) { src: MirSource<'tcx>, 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(); let id = tcx.hir().as_local_node_id(def_id).unwrap();
if !tcx.has_attr(def_id, "rustc_mir") { if !tcx.has_attr(def_id, "rustc_mir") {
debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id)); 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, fn run_pass<'a, 'tcx>(&self,
_tcx: TyCtxt<'a, 'tcx, 'tcx>, _tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource, _src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir); debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
simplify_cfg(mir); simplify_cfg(mir);
@ -298,7 +298,7 @@ pub struct SimplifyLocals;
impl MirPass for SimplifyLocals { impl MirPass for SimplifyLocals {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
_: MirSource, _: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
let mut marker = DeclMarker { locals: BitSet::new_empty(mir.local_decls.len()) }; let mut marker = DeclMarker { locals: BitSet::new_empty(mir.local_decls.len()) };
marker.visit_mir(mir); marker.visit_mir(mir);

View file

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

View file

@ -39,7 +39,7 @@ pub struct UniformArrayMoveOut;
impl MirPass for UniformArrayMoveOut { impl MirPass for UniformArrayMoveOut {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource, _src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
let mut patch = MirPatch::new(mir); let mut patch = MirPatch::new(mir);
{ {
@ -161,7 +161,7 @@ pub struct RestoreSubsliceArrayMoveOut;
impl MirPass for RestoreSubsliceArrayMoveOut { impl MirPass for RestoreSubsliceArrayMoveOut {
fn run_pass<'a, 'tcx>(&self, fn run_pass<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
_src: MirSource, _src: MirSource<'tcx>,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
let mut patch = MirPatch::new(mir); 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>( pub fn dump_mir<'a, 'tcx, V: Idx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
pass_name: &str, pass_name: &str,
source: MirSource, source: MirSource<'tcx>,
mir: &Mir<'tcx>, mir: &Mir<'tcx>,
map: &impl LiveVariableMap<LiveVar = V>, map: &impl LiveVariableMap<LiveVar = V>,
result: &LivenessResult<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(|| { let node_path = item_path::with_forced_impl_filename_line(|| {
// see notes on #41697 below // 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); 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>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
pass_name: &str, pass_name: &str,
node_path: &str, node_path: &str,
source: MirSource, source: MirSource<'tcx>,
mir: &Mir<'tcx>, mir: &Mir<'tcx>,
map: &dyn LiveVariableMap<LiveVar = V>, map: &dyn LiveVariableMap<LiveVar = V>,
result: &LivenessResult<V>, result: &LivenessResult<V>,
) { ) {
let mut file_path = PathBuf::new(); let mut file_path = PathBuf::new();
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); 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); let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name);
file_path.push(&file_name); file_path.push(&file_name);
let _ = fs::File::create(&file_path).and_then(|mut file| { 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>( pub fn write_mir_fn<'a, 'tcx, V: Idx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource, src: MirSource<'tcx>,
mir: &Mir<'tcx>, mir: &Mir<'tcx>,
map: &dyn LiveVariableMap<LiveVar = V>, map: &dyn LiveVariableMap<LiveVar = V>,
w: &mut dyn Write, w: &mut dyn Write,

View file

@ -1,4 +1,3 @@
use rustc::hir;
use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::mir::*; use rustc::mir::*;
use rustc::mir::visit::Visitor; use rustc::mir::visit::Visitor;
@ -69,7 +68,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
pass_num: Option<&dyn Display>, pass_num: Option<&dyn Display>,
pass_name: &str, pass_name: &str,
disambiguator: &dyn Display, disambiguator: &dyn Display,
source: MirSource, source: MirSource<'tcx>,
mir: &Mir<'tcx>, mir: &Mir<'tcx>,
extra_data: F, extra_data: F,
) where ) where
@ -81,7 +80,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
let node_path = item_path::with_forced_impl_filename_line(|| { let node_path = item_path::with_forced_impl_filename_line(|| {
// see notes on #41697 below // see notes on #41697 below
tcx.item_path_str(source.def_id) tcx.item_path_str(source.def_id())
}); });
dump_matched_mir_node( dump_matched_mir_node(
tcx, tcx,
@ -98,7 +97,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
pub fn dump_enabled<'a, 'gcx, 'tcx>( pub fn dump_enabled<'a, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>,
pass_name: &str, pass_name: &str,
source: MirSource, source: MirSource<'tcx>,
) -> bool { ) -> bool {
let filters = match tcx.sess.opts.debugging_opts.dump_mir { let filters = match tcx.sess.opts.debugging_opts.dump_mir {
None => return false, None => return false,
@ -106,7 +105,7 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>(
}; };
let node_path = item_path::with_forced_impl_filename_line(|| { let node_path = item_path::with_forced_impl_filename_line(|| {
// see notes on #41697 below // see notes on #41697 below
tcx.item_path_str(source.def_id) tcx.item_path_str(source.def_id())
}); });
filters.split('|').any(|or_filter| { filters.split('|').any(|or_filter| {
or_filter.split('&').all(|and_filter| { or_filter.split('&').all(|and_filter| {
@ -125,7 +124,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
pass_name: &str, pass_name: &str,
node_path: &str, node_path: &str,
disambiguator: &dyn Display, disambiguator: &dyn Display,
source: MirSource, source: MirSource<'tcx>,
mir: &Mir<'tcx>, mir: &Mir<'tcx>,
mut extra_data: F, mut extra_data: F,
) where ) where
@ -151,7 +150,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
let _: io::Result<()> = try { let _: io::Result<()> = try {
let mut file = let mut file =
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?; 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_num: Option<&dyn Display>,
pass_name: &str, pass_name: &str,
disambiguator: &dyn Display, disambiguator: &dyn Display,
source: MirSource, source: MirSource<'tcx>,
) -> PathBuf { ) -> PathBuf {
let promotion_id = match source.promoted { let promotion_id = match source.promoted {
Some(id) => format!("-{:?}", id), Some(id) => format!("-{:?}", id),
@ -184,13 +183,32 @@ fn dump_path(
let mut file_path = PathBuf::new(); let mut file_path = PathBuf::new();
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
let item_name = tcx.hir() let item_name = tcx
.def_path(source.def_id) .def_path(source.def_id())
.to_filename_friendly_no_crate(); .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!( let file_name = format!(
"rustc.{}{}{}.{}.{}.{}", "rustc.{}{}{}{}.{}.{}.{}",
item_name, item_name,
shim_disambiguator,
promotion_id, promotion_id,
pass_num, pass_num,
pass_name, pass_name,
@ -213,7 +231,7 @@ pub(crate) fn create_dump_file(
pass_num: Option<&dyn Display>, pass_num: Option<&dyn Display>,
pass_name: &str, pass_name: &str,
disambiguator: &dyn Display, disambiguator: &dyn Display,
source: MirSource, source: MirSource<'tcx>,
) -> io::Result<fs::File> { ) -> io::Result<fs::File> {
let file_path = dump_path(tcx, extension, pass_num, pass_name, disambiguator, source); let file_path = dump_path(tcx, extension, pass_num, pass_name, disambiguator, source);
if let Some(parent) = file_path.parent() { 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() { for (i, mir) in mir.promoted.iter_enumerated() {
writeln!(w, "")?; writeln!(w, "")?;
let src = MirSource { let src = MirSource {
def_id, instance: ty::InstanceDef::Item(def_id),
promoted: Some(i), promoted: Some(i),
}; };
write_mir_fn(tcx, src, mir, &mut |_, _| Ok(()), w)?; 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>( pub fn write_mir_fn<'a, 'gcx, 'tcx, F>(
tcx: TyCtxt<'a, 'gcx, 'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>,
src: MirSource, src: MirSource<'tcx>,
mir: &Mir<'tcx>, mir: &Mir<'tcx>,
extra_data: &mut F, extra_data: &mut F,
w: &mut dyn Write, w: &mut dyn Write,
@ -528,7 +546,7 @@ fn write_scope_tree(
/// local variables (both user-defined bindings and compiler temporaries). /// local variables (both user-defined bindings and compiler temporaries).
pub fn write_mir_intro<'a, 'gcx, 'tcx>( pub fn write_mir_intro<'a, 'gcx, 'tcx>(
tcx: TyCtxt<'a, 'gcx, 'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>,
src: MirSource, src: MirSource<'tcx>,
mir: &Mir<'_>, mir: &Mir<'_>,
w: &mut dyn Write, w: &mut dyn Write,
) -> io::Result<()> { ) -> io::Result<()> {
@ -570,45 +588,49 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>(
fn write_mir_sig( fn write_mir_sig(
tcx: TyCtxt<'_, '_, '_>, tcx: TyCtxt<'_, '_, '_>,
src: MirSource, src: MirSource<'tcx>,
mir: &Mir<'_>, mir: &Mir<'_>,
w: &mut dyn Write, w: &mut dyn Write,
) -> io::Result<()> { ) -> io::Result<()> {
let id = tcx.hir().as_local_node_id(src.def_id).unwrap(); use rustc::hir::def::Def;
let body_owner_kind = tcx.hir().body_owner_kind(id);
match (body_owner_kind, src.promoted) { trace!("write_mir_sig: {:?}", src.instance);
(_, Some(i)) => write!(w, "{:?} in", i)?, let descr = tcx.describe_def(src.def_id());
(hir::BodyOwnerKind::Closure, _) | let is_function = match descr {
(hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?, Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true,
(hir::BodyOwnerKind::Const, _) => write!(w, "const")?, _ => tcx.is_closure(src.def_id()),
(hir::BodyOwnerKind::Static(hir::MutImmutable), _) => write!(w, "static")?, };
(hir::BodyOwnerKind::Static(hir::MutMutable), _) => write!(w, "static mut")?, 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(|| { item_path::with_forced_impl_filename_line(|| {
// see notes on #41697 elsewhere // 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) { if src.promoted.is_none() && is_function {
(hir::BodyOwnerKind::Closure, None) | write!(w, "(")?;
(hir::BodyOwnerKind::Fn, None) => {
write!(w, "(")?;
// fn argument types. // fn argument types.
for (i, arg) in mir.args_iter().enumerate() { for (i, arg) in mir.args_iter().enumerate() {
if i != 0 { if i != 0 {
write!(w, ", ")?; write!(w, ", ")?;
}
write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?;
} }
write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?;
}
write!(w, ") -> {}", mir.return_ty())?; write!(w, ") -> {}", mir.return_ty())?;
} } else {
(hir::BodyOwnerKind::Const, _) | (hir::BodyOwnerKind::Static(_), _) | (_, Some(_)) => { assert_eq!(mir.arg_count, 0);
assert_eq!(mir.arg_count, 0); write!(w, ": {} =", mir.return_ty())?;
write!(w, ": {} =", mir.return_ty())?;
}
} }
if let Some(yield_ty) = mir.yield_ty { if let Some(yield_ty) = mir.yield_ty {
@ -616,6 +638,9 @@ fn write_mir_sig(
writeln!(w, "yields {}", yield_ty)?; writeln!(w, "yields {}", yield_ty)?;
} }
write!(w, " ")?;
// Next thing that gets printed is the opening {
Ok(()) Ok(())
} }