diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 91fc12639baf5..955f834e40398 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -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(_) |
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 1fca104cd3825..84fdbb9423e0a 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -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<'_>>,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 19ff47f9c390d..add07b1ddfe05 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -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
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 942e7a1f1bbbd..7f3e4a2e1bc4f 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -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)
diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs
index dab96faaa2a5e..88042d64e96b7 100644
--- a/src/librustc_mir/transform/add_call_guards.rs
+++ b/src/librustc_mir/transform/add_call_guards.rs
@@ -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);
     }
diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs
index 1492f0c50a31a..4d4c89b8b6a40 100644
--- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs
+++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs
@@ -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());
     }
 }
 
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index 7bfcd318afe2d..e66c11aa36e0e 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -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 {
diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs
index 240ef7c8ba42a..890d2c56f42b2 100644
--- a/src/librustc_mir/transform/cleanup_post_borrowck.rs
+++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs
@@ -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);
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index dd1f37a591888..018f71c39e513 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -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 {
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index 4789c35740eb3..7d907ca3a215e 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -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.
diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs
index 669384e31dac3..9061dfff76fe8 100644
--- a/src/librustc_mir/transform/deaggregator.rs
+++ b/src/librustc_mir/transform/deaggregator.rs
@@ -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;
diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs
index d7f697a320049..81e48fe2dbe3b 100644
--- a/src/librustc_mir/transform/dump_mir.rs
+++ b/src/librustc_mir/transform/dump_mir.rs
@@ -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) {
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 4aaa0be7964a4..6e093a7e240b3 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -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)) => {
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index b555a2aa83ee3..d59bb3ec5b1c0 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -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);
     }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 9897f9833ca62..33d98d8f076c8 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -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;
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 4fddf6f8e09c2..4cb7826698466 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -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;
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index 21772e1f1cd5b..290915763e275 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -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 {
diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs
index aa248ba7c53df..3d1f55e530e62 100644
--- a/src/librustc_mir/transform/lower_128bit.rs
+++ b/src/librustc_mir/transform/lower_128bit.rs
@@ -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;
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index cc37a8381f234..44061e689b3be 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -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"),
diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs
index 15b59d36d363c..089d9b9b54454 100644
--- a/src/librustc_mir/transform/no_landing_pads.rs
+++ b/src/librustc_mir/transform/no_landing_pads.rs
@@ -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)
     }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index ab4e3ad23f69a..76b8b83031a0a 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -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) {
diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs
index 4fcb4c10f9e6d..68832b73ccd87 100644
--- a/src/librustc_mir/transform/remove_noop_landing_pads.rs
+++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs
@@ -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);
     }
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 806c1c1cca457..40e02e712c156 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -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));
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index 90486d1566413..14e7895af0419 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -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);
diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs
index 0dc89bfe14709..3c4d1227a691c 100644
--- a/src/librustc_mir/transform/simplify_branches.rs
+++ b/src/librustc_mir/transform/simplify_branches.rs
@@ -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();
diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs
index 09918436817f3..fd8d68a482262 100644
--- a/src/librustc_mir/transform/uniform_array_move_out.rs
+++ b/src/librustc_mir/transform/uniform_array_move_out.rs
@@ -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);
         {
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index 08ef58a232170..847699cc500c9 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -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,
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 2e1fc756833b8..1357f8fe79a0d 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -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, ") -> {}", mir.return_ty())?;
-        }
-        (hir::BodyOwnerKind::Const, _) | (hir::BodyOwnerKind::Static(_), _) | (_, Some(_)) => {
-            assert_eq!(mir.arg_count, 0);
-            write!(w, ": {} =", mir.return_ty())?;
+            write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].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(())
 }