about summary refs log tree commit diff
path: root/src/librustc_mir/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_mir/util')
-rw-r--r--src/librustc_mir/util/aggregate.rs6
-rw-r--r--src/librustc_mir/util/alignment.rs8
-rw-r--r--src/librustc_mir/util/borrowck_errors.rs37
-rw-r--r--src/librustc_mir/util/collect_writes.rs11
-rw-r--r--src/librustc_mir/util/def_use.rs10
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs103
-rw-r--r--src/librustc_mir/util/graphviz.rs4
-rw-r--r--src/librustc_mir/util/liveness.rs18
-rw-r--r--src/librustc_mir/util/patch.rs4
-rw-r--r--src/librustc_mir/util/pretty.rs321
10 files changed, 380 insertions, 142 deletions
diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs
index 927c8f6dfb2..e77d264b7ce 100644
--- a/src/librustc_mir/util/aggregate.rs
+++ b/src/librustc_mir/util/aggregate.rs
@@ -1,7 +1,7 @@
-use rustc::mir::*;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::{Ty, TyCtxt};
 use rustc_index::vec::Idx;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{Ty, TyCtxt};
+use rustc_target::abi::VariantIdx;
 
 use std::iter::TrustedLen;
 
diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs
index d7f2abfbe99..202e5e27f1d 100644
--- a/src/librustc_mir/util/alignment.rs
+++ b/src/librustc_mir/util/alignment.rs
@@ -1,5 +1,5 @@
-use rustc::mir::*;
-use rustc::ty::{self, TyCtxt};
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt};
 
 /// Returns `true` if this place is allowed to be less aligned
 /// than its containing struct (because it is within a packed
@@ -8,7 +8,7 @@ pub fn is_disaligned<'tcx, L>(
     tcx: TyCtxt<'tcx>,
     local_decls: &L,
     param_env: ty::ParamEnv<'tcx>,
-    place: &Place<'tcx>,
+    place: Place<'tcx>,
 ) -> bool
 where
     L: HasLocalDecls<'tcx>,
@@ -34,7 +34,7 @@ where
     }
 }
 
-fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: &Place<'tcx>) -> bool
+fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: Place<'tcx>) -> bool
 where
     L: HasLocalDecls<'tcx>,
 {
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs
index d8ee059f1a6..808dd833774 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/src/librustc_mir/util/borrowck_errors.rs
@@ -1,10 +1,10 @@
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::{MultiSpan, Span};
 
 impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
     crate fn cannot_move_when_borrowed(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> {
-        struct_span_err!(self, span, E0505, "cannot move out of `{}` because it is borrowed", desc,)
+        struct_span_err!(self, span, E0505, "cannot move out of {} because it is borrowed", desc,)
     }
 
     crate fn cannot_use_when_mutably_borrowed(
@@ -18,12 +18,12 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
             self,
             span,
             E0503,
-            "cannot use `{}` because it was mutably borrowed",
+            "cannot use {} because it was mutably borrowed",
             desc,
         );
 
-        err.span_label(borrow_span, format!("borrow of `{}` occurs here", borrow_desc));
-        err.span_label(span, format!("use of borrowed `{}`", borrow_desc));
+        err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_desc));
+        err.span_label(span, format!("use of borrowed {}", borrow_desc));
         err
     }
 
@@ -53,12 +53,12 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
         old_load_end_span: Option<Span>,
     ) -> DiagnosticBuilder<'cx> {
         let via =
-            |msg: &str| if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) };
+            |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) };
         let mut err = struct_span_err!(
             self,
             new_loan_span,
             E0499,
-            "cannot borrow `{}`{} as mutable more than once at a time",
+            "cannot borrow {}{} as mutable more than once at a time",
             desc,
             via(opt_via),
         );
@@ -103,7 +103,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
             self,
             new_loan_span,
             E0524,
-            "two closures require unique access to `{}` at the same time",
+            "two closures require unique access to {} at the same time",
             desc,
         );
         if old_loan_span == new_loan_span {
@@ -136,7 +136,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
             self,
             new_loan_span,
             E0500,
-            "closure requires unique access to `{}` but {} is already borrowed{}",
+            "closure requires unique access to {} but {} is already borrowed{}",
             desc_new,
             noun_old,
             old_opt_via,
@@ -168,7 +168,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
             self,
             new_loan_span,
             E0501,
-            "cannot borrow `{}`{} as {} because previous closure \
+            "cannot borrow {}{} as {} because previous closure \
              requires unique access",
             desc_new,
             opt_via,
@@ -201,13 +201,12 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
         old_load_end_span: Option<Span>,
     ) -> DiagnosticBuilder<'cx> {
         let via =
-            |msg: &str| if msg.is_empty() { msg.to_string() } else { format!(" (via `{}`)", msg) };
+            |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {})", msg) };
         let mut err = struct_span_err!(
             self,
             span,
             E0502,
-            "cannot borrow `{}`{} as {} because {} is also borrowed \
-             as {}{}",
+            "cannot borrow {}{} as {} because {} is also borrowed as {}{}",
             desc_new,
             via(msg_new),
             kind_new,
@@ -225,7 +224,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
             err.span_label(
                 span,
                 format!(
-                    "{} borrow of `{}` -- which overlaps with `{}` -- occurs here",
+                    "{} borrow of {} -- which overlaps with {} -- occurs here",
                     kind_new, msg_new, msg_old,
                 ),
             );
@@ -248,12 +247,12 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
             self,
             span,
             E0506,
-            "cannot assign to `{}` because it is borrowed",
+            "cannot assign to {} because it is borrowed",
             desc,
         );
 
-        err.span_label(borrow_span, format!("borrow of `{}` occurs here", desc));
-        err.span_label(span, format!("assignment to borrowed `{}` occurs here", desc));
+        err.span_label(borrow_span, format!("borrow of {} occurs here", desc));
+        err.span_label(span, format!("assignment to borrowed {} occurs here", desc));
         err
     }
 
@@ -264,7 +263,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
         is_arg: bool,
     ) -> DiagnosticBuilder<'cx> {
         let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
-        struct_span_err!(self, span, E0384, "cannot assign {} `{}`", msg, desc,)
+        struct_span_err!(self, span, E0384, "cannot assign {} {}", msg, desc)
     }
 
     crate fn cannot_assign(&self, span: Span, desc: &str) -> DiagnosticBuilder<'cx> {
@@ -362,7 +361,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
             self,
             mutate_span,
             E0510,
-            "cannot {} `{}` in {}",
+            "cannot {} {} in {}",
             action,
             immutable_place,
             immutable_section,
diff --git a/src/librustc_mir/util/collect_writes.rs b/src/librustc_mir/util/collect_writes.rs
index 6cd21316496..ecf3b08a96e 100644
--- a/src/librustc_mir/util/collect_writes.rs
+++ b/src/librustc_mir/util/collect_writes.rs
@@ -1,7 +1,6 @@
-use rustc::mir::visit::PlaceContext;
-use rustc::mir::visit::Visitor;
-use rustc::mir::ReadOnlyBodyAndCache;
-use rustc::mir::{Local, Location};
+use rustc_middle::mir::visit::PlaceContext;
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::{Body, Local, Location};
 
 crate trait FindAssignments {
     // Finds all statements that assign directly to local (i.e., X = ...)
@@ -9,10 +8,10 @@ crate trait FindAssignments {
     fn find_assignments(&self, local: Local) -> Vec<Location>;
 }
 
-impl<'a, 'tcx> FindAssignments for ReadOnlyBodyAndCache<'a, 'tcx> {
+impl<'tcx> FindAssignments for Body<'tcx> {
     fn find_assignments(&self, local: Local) -> Vec<Location> {
         let mut visitor = FindLocalAssignmentVisitor { needle: local, locations: vec![] };
-        visitor.visit_body(*self);
+        visitor.visit_body(self);
         visitor.locations
     }
 }
diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs
index aa9ddbdbda9..6b5f6aa991c 100644
--- a/src/librustc_mir/util/def_use.rs
+++ b/src/librustc_mir/util/def_use.rs
@@ -1,11 +1,11 @@
 //! Def-use analysis.
 
-use rustc::mir::visit::{MutVisitor, PlaceContext, Visitor};
-use rustc::mir::{
+use rustc_index::vec::IndexVec;
+use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
+use rustc_middle::mir::{
     Body, BodyAndCache, Local, Location, PlaceElem, ReadOnlyBodyAndCache, VarDebugInfo,
 };
-use rustc::ty::TyCtxt;
-use rustc_index::vec::IndexVec;
+use rustc_middle::ty::TyCtxt;
 use std::mem;
 
 pub struct DefUseAnalysis {
@@ -38,7 +38,7 @@ impl DefUseAnalysis {
             var_debug_info_index: 0,
             in_var_debug_info: false,
         };
-        finder.visit_body(body);
+        finder.visit_body(&body);
         self.info = finder.info
     }
 
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index f7239ae55fa..e3a96ca7896 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -1,13 +1,13 @@
 use crate::util::patch::MirPatch;
-use rustc::middle::lang_items;
-use rustc::mir::*;
-use rustc::traits::Reveal;
-use rustc::ty::layout::VariantIdx;
-use rustc::ty::subst::SubstsRef;
-use rustc::ty::util::IntTypeExt;
-use rustc::ty::{self, Ty, TyCtxt};
 use rustc_hir as hir;
+use rustc_hir::lang_items;
 use rustc_index::vec::Idx;
+use rustc_middle::mir::*;
+use rustc_middle::traits::Reveal;
+use rustc_middle::ty::subst::SubstsRef;
+use rustc_middle::ty::util::IntTypeExt;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_target::abi::VariantIdx;
 use std::fmt;
 
 use std::convert::TryInto;
@@ -100,7 +100,7 @@ where
 
     source_info: SourceInfo,
 
-    place: &'l Place<'tcx>,
+    place: Place<'tcx>,
     path: D::Path,
     succ: BasicBlock,
     unwind: Unwind,
@@ -109,7 +109,7 @@ where
 pub fn elaborate_drop<'b, 'tcx, D>(
     elaborator: &mut D,
     source_info: SourceInfo,
-    place: &Place<'tcx>,
+    place: Place<'tcx>,
     path: D::Path,
     succ: BasicBlock,
     unwind: Unwind,
@@ -126,7 +126,7 @@ where
     D: DropElaborator<'b, 'tcx>,
     'tcx: 'b,
 {
-    fn place_ty(&self, place: &Place<'tcx>) -> Ty<'tcx> {
+    fn place_ty(&self, place: Place<'tcx>) -> Ty<'tcx> {
         place.ty(self.elaborator.body(), self.tcx()).ty
     }
 
@@ -168,7 +168,7 @@ where
                 self.elaborator.patch().patch_terminator(
                     bb,
                     TerminatorKind::Drop {
-                        location: *self.place,
+                        location: self.place,
                         target: self.succ,
                         unwind: self.unwind.into_option(),
                     },
@@ -195,7 +195,7 @@ where
     /// (the move path is `None` if the field is a rest field).
     fn move_paths_for_fields(
         &self,
-        base_place: &Place<'tcx>,
+        base_place: Place<'tcx>,
         variant_path: D::Path,
         variant: &'tcx ty::VariantDef,
         substs: SubstsRef<'tcx>,
@@ -219,7 +219,7 @@ where
 
     fn drop_subpath(
         &mut self,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         path: Option<D::Path>,
         succ: BasicBlock,
         unwind: Unwind,
@@ -267,12 +267,10 @@ where
     ) -> Vec<BasicBlock> {
         Some(succ)
             .into_iter()
-            .chain(fields.iter().rev().zip(unwind_ladder).map(
-                |(&(ref place, path), &unwind_succ)| {
-                    succ = self.drop_subpath(place, path, succ, unwind_succ);
-                    succ
-                },
-            ))
+            .chain(fields.iter().rev().zip(unwind_ladder).map(|(&(place, path), &unwind_succ)| {
+                succ = self.drop_subpath(place, path, succ, unwind_succ);
+                succ
+            }))
             .collect()
     }
 
@@ -315,7 +313,7 @@ where
         debug!("drop_ladder({:?}, {:?})", self, fields);
 
         let mut fields = fields;
-        fields.retain(|&(ref place, _)| {
+        fields.retain(|&(place, _)| {
             self.place_ty(place).needs_drop(self.tcx(), self.elaborator.param_env())
         });
 
@@ -364,7 +362,7 @@ where
         let unwind_succ =
             self.unwind.map(|unwind| self.box_free_block(adt, substs, unwind, Unwind::InCleanup));
 
-        self.drop_subpath(&interior, interior_path, succ, unwind_succ)
+        self.drop_subpath(interior, interior_path, succ, unwind_succ)
     }
 
     fn open_drop_for_adt(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock {
@@ -439,8 +437,7 @@ where
                     self.place.clone(),
                     ProjectionElem::Downcast(Some(variant.ident.name), variant_index),
                 );
-                let fields =
-                    self.move_paths_for_fields(&base_place, variant_path, &variant, substs);
+                let fields = self.move_paths_for_fields(base_place, variant_path, &variant, substs);
                 values.push(discr.val);
                 if let Unwind::To(unwind) = unwind {
                     // We can't use the half-ladder from the original
@@ -527,9 +524,9 @@ where
         // way lies only trouble.
         let discr_ty = adt.repr.discr_type().to_ty(self.tcx());
         let discr = Place::from(self.new_temp(discr_ty));
-        let discr_rv = Rvalue::Discriminant(*self.place);
+        let discr_rv = Rvalue::Discriminant(self.place);
         let switch_block = BasicBlockData {
-            statements: vec![self.assign(&discr, discr_rv)],
+            statements: vec![self.assign(discr, discr_rv)],
             terminator: Some(Terminator {
                 source_info: self.source_info,
                 kind: TerminatorKind::SwitchInt {
@@ -549,7 +546,7 @@ where
         debug!("destructor_call_block({:?}, {:?})", self, succ);
         let tcx = self.tcx();
         let drop_trait = tcx.lang_items().drop_trait().unwrap();
-        let drop_fn = tcx.associated_items(drop_trait).in_definition_order().nth(0).unwrap();
+        let drop_fn = tcx.associated_items(drop_trait).in_definition_order().next().unwrap();
         let ty = self.place_ty(self.place);
         let substs = tcx.mk_substs_trait(ty, &[]);
 
@@ -560,11 +557,11 @@ where
 
         let result = BasicBlockData {
             statements: vec![self.assign(
-                &Place::from(ref_place),
+                Place::from(ref_place),
                 Rvalue::Ref(
                     tcx.lifetimes.re_erased,
                     BorrowKind::Mut { allow_two_phase_borrow: false },
-                    *self.place,
+                    self.place,
                 ),
             )],
             terminator: Some(Terminator {
@@ -607,7 +604,7 @@ where
         &mut self,
         succ: BasicBlock,
         cur: Local,
-        length_or_end: &Place<'tcx>,
+        length_or_end: Place<'tcx>,
         ety: Ty<'tcx>,
         unwind: Unwind,
         ptr_based: bool,
@@ -617,7 +614,7 @@ where
         let tcx = self.tcx();
 
         let ptr_ty = tcx.mk_ptr(ty::TypeAndMut { ty: ety, mutbl: hir::Mutability::Mut });
-        let ptr = &Place::from(self.new_temp(ptr_ty));
+        let ptr = Place::from(self.new_temp(ptr_ty));
         let can_go = Place::from(self.new_temp(tcx.types.bool));
 
         let one = self.constant_usize(1);
@@ -631,7 +628,7 @@ where
         };
 
         let drop_block = BasicBlockData {
-            statements: vec![self.assign(ptr, ptr_next), self.assign(&Place::from(cur), cur_next)],
+            statements: vec![self.assign(ptr, ptr_next), self.assign(Place::from(cur), cur_next)],
             is_cleanup: unwind.is_cleanup(),
             terminator: Some(Terminator {
                 source_info: self.source_info,
@@ -643,8 +640,8 @@ where
 
         let loop_block = BasicBlockData {
             statements: vec![self.assign(
-                &can_go,
-                Rvalue::BinaryOp(BinOp::Eq, copy(Place::from(cur)), copy(*length_or_end)),
+                can_go,
+                Rvalue::BinaryOp(BinOp::Eq, copy(Place::from(cur)), copy(length_or_end)),
             )],
             is_cleanup: unwind.is_cleanup(),
             terminator: Some(Terminator {
@@ -703,16 +700,16 @@ where
             }
         }
 
-        let move_ = |place: &Place<'tcx>| Operand::Move(*place);
-        let elem_size = &Place::from(self.new_temp(tcx.types.usize));
-        let len = &Place::from(self.new_temp(tcx.types.usize));
+        let move_ = |place: Place<'tcx>| Operand::Move(place);
+        let elem_size = Place::from(self.new_temp(tcx.types.usize));
+        let len = Place::from(self.new_temp(tcx.types.usize));
 
         static USIZE_SWITCH_ZERO: &[u128] = &[0];
 
         let base_block = BasicBlockData {
             statements: vec![
                 self.assign(elem_size, Rvalue::NullaryOp(NullOp::SizeOf, ety)),
-                self.assign(len, Rvalue::Len(*self.place)),
+                self.assign(len, Rvalue::Len(self.place)),
             ],
             is_cleanup: self.unwind.is_cleanup(),
             terminator: Some(Terminator {
@@ -731,7 +728,7 @@ where
         self.elaborator.patch().new_block(base_block)
     }
 
-    /// Ceates a pair of drop-loops of `place`, which drops its contents, even
+    /// Creates a pair of drop-loops of `place`, which drops its contents, even
     /// in the case of 1 panic. If `ptr_based`, creates a pointer loop,
     /// otherwise create an index loop.
     fn drop_loop_pair(
@@ -748,10 +745,10 @@ where
         let length_or_end = if ptr_based { Place::from(self.new_temp(iter_ty)) } else { length };
 
         let unwind = self.unwind.map(|unwind| {
-            self.drop_loop(unwind, cur, &length_or_end, ety, Unwind::InCleanup, ptr_based)
+            self.drop_loop(unwind, cur, length_or_end, ety, Unwind::InCleanup, ptr_based)
         });
 
-        let loop_block = self.drop_loop(self.succ, cur, &length_or_end, ety, unwind, ptr_based);
+        let loop_block = self.drop_loop(self.succ, cur, length_or_end, ety, unwind, ptr_based);
 
         let cur = Place::from(cur);
         let drop_block_stmts = if ptr_based {
@@ -761,17 +758,17 @@ where
             // cur = tmp as *mut T;
             // end = Offset(cur, len);
             vec![
-                self.assign(&tmp, Rvalue::AddressOf(Mutability::Mut, *self.place)),
-                self.assign(&cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)),
+                self.assign(tmp, Rvalue::AddressOf(Mutability::Mut, self.place)),
+                self.assign(cur, Rvalue::Cast(CastKind::Misc, Operand::Move(tmp), iter_ty)),
                 self.assign(
-                    &length_or_end,
+                    length_or_end,
                     Rvalue::BinaryOp(BinOp::Offset, Operand::Copy(cur), Operand::Move(length)),
                 ),
             ]
         } else {
             // cur = 0 (length already pushed)
             let zero = self.constant_usize(0);
-            vec![self.assign(&cur, Rvalue::Use(zero))]
+            vec![self.assign(cur, Rvalue::Use(zero))]
         };
         let drop_block = self.elaborator.patch().new_block(BasicBlockData {
             statements: drop_block_stmts,
@@ -798,8 +795,8 @@ where
     fn open_drop(&mut self) -> BasicBlock {
         let ty = self.place_ty(self.place);
         match ty.kind {
-            ty::Closure(def_id, substs) => {
-                let tys: Vec<_> = substs.as_closure().upvar_tys(def_id, self.tcx()).collect();
+            ty::Closure(_, substs) => {
+                let tys: Vec<_> = substs.as_closure().upvar_tys().collect();
                 self.open_drop_for_tuple(&tys)
             }
             // Note that `elaborate_drops` only drops the upvars of a generator,
@@ -808,8 +805,8 @@ where
             // This should only happen for the self argument on the resume function.
             // It effetively only contains upvars until the generator transformation runs.
             // See librustc_body/transform/generator.rs for more details.
-            ty::Generator(def_id, substs, _) => {
-                let tys: Vec<_> = substs.as_generator().upvar_tys(def_id, self.tcx()).collect();
+            ty::Generator(_, substs, _) => {
+                let tys: Vec<_> = substs.as_generator().upvar_tys().collect();
                 self.open_drop_for_tuple(&tys)
             }
             ty::Tuple(..) => {
@@ -872,7 +869,7 @@ where
         debug!("drop_flag_reset_block({:?},{:?})", self, mode);
 
         let block = self.new_block(unwind, TerminatorKind::Goto { target: succ });
-        let block_start = Location { block: block, statement_index: 0 };
+        let block_start = Location { block, statement_index: 0 };
         self.elaborator.clear_drop_flag(block_start, self.path, mode);
         block
     }
@@ -921,7 +918,7 @@ where
 
         let call = TerminatorKind::Call {
             func: Operand::function_handle(tcx, free_func, substs, self.source_info.span),
-            args: args,
+            args,
             destination: Some((unit_temp, target)),
             cleanup: None,
             from_hir_call: false,
@@ -935,7 +932,7 @@ where
 
     fn drop_block(&mut self, target: BasicBlock, unwind: Unwind) -> BasicBlock {
         let block =
-            TerminatorKind::Drop { location: *self.place, target, unwind: unwind.into_option() };
+            TerminatorKind::Drop { location: self.place, target, unwind: unwind.into_option() };
         self.new_block(unwind, block)
     }
 
@@ -992,7 +989,7 @@ where
         })
     }
 
-    fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
-        Statement { source_info: self.source_info, kind: StatementKind::Assign(box (*lhs, rhs)) }
+    fn assign(&self, lhs: Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
+        Statement { source_info: self.source_info, kind: StatementKind::Assign(box (lhs, rhs)) }
     }
 }
diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs
index 8291bc95880..aed29a076a4 100644
--- a/src/librustc_mir/util/graphviz.rs
+++ b/src/librustc_mir/util/graphviz.rs
@@ -1,7 +1,7 @@
-use rustc::mir::*;
-use rustc::ty::TyCtxt;
 use rustc_hir::def_id::DefId;
 use rustc_index::vec::Idx;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
 use std::fmt::Debug;
 use std::io::{self, Write};
 
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index b12ad1e4c15..a1b7634f0c6 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -26,15 +26,15 @@
 
 use crate::transform::MirSource;
 use crate::util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
-use rustc::mir::visit::{
-    MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor,
-};
-use rustc::mir::Local;
-use rustc::mir::*;
-use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::work_queue::WorkQueue;
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::visit::{
+    MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor,
+};
+use rustc_middle::mir::Local;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt};
 use std::fs;
 use std::io::{self, BufWriter, Write};
 use std::path::{Path, PathBuf};
@@ -265,7 +265,7 @@ pub fn dump_mir<'tcx>(
     body: &Body<'tcx>,
     result: &LivenessResult,
 ) {
-    if !dump_enabled(tcx, pass_name, source) {
+    if !dump_enabled(tcx, pass_name, source.def_id()) {
         return;
     }
     let node_path = ty::print::with_forced_impl_filename_line(|| {
@@ -293,7 +293,7 @@ fn dump_matched_mir_node<'tcx>(
         writeln!(file, "// MIR local liveness analysis for `{}`", node_path)?;
         writeln!(file, "// source = {:?}", source)?;
         writeln!(file, "// pass_name = {}", pass_name)?;
-        writeln!(file, "")?;
+        writeln!(file)?;
         write_mir_fn(tcx, source, body, &mut file, result)?;
         Ok(())
     });
@@ -316,7 +316,7 @@ pub fn write_mir_fn<'tcx>(
         write_basic_block(tcx, block, body, &mut |_, _| Ok(()), w)?;
         print(w, "   ", &result.outs)?;
         if block.index() + 1 != body.basic_blocks().len() {
-            writeln!(w, "")?;
+            writeln!(w)?;
         }
     }
 
diff --git a/src/librustc_mir/util/patch.rs b/src/librustc_mir/util/patch.rs
index 473692a43f3..46f42f4db05 100644
--- a/src/librustc_mir/util/patch.rs
+++ b/src/librustc_mir/util/patch.rs
@@ -1,6 +1,6 @@
-use rustc::mir::*;
-use rustc::ty::Ty;
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::mir::*;
+use rustc_middle::ty::Ty;
 use rustc_span::Span;
 
 /// This struct represents a patch to MIR, which can add
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 6fd8f06fe8f..a81fcb54580 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -1,11 +1,17 @@
 use super::graphviz::write_mir_fn_graphviz;
 use crate::transform::MirSource;
-use rustc::mir::visit::Visitor;
-use rustc::mir::*;
-use rustc::ty::{self, TyCtxt};
+use either::Either;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_index::vec::Idx;
+use rustc_middle::mir::interpret::{
+    read_target_uint, AllocId, Allocation, ConstValue, GlobalAlloc,
+};
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitor};
+use rustc_target::abi::Size;
+use std::collections::BTreeSet;
 use std::fmt::Display;
 use std::fmt::Write as _;
 use std::fs;
@@ -73,34 +79,21 @@ pub fn dump_mir<'tcx, F>(
 ) where
     F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
 {
-    if !dump_enabled(tcx, pass_name, source) {
+    if !dump_enabled(tcx, pass_name, source.def_id()) {
         return;
     }
 
-    let node_path = ty::print::with_forced_impl_filename_line(|| {
-        // see notes on #41697 below
-        tcx.def_path_str(source.def_id())
-    });
-    dump_matched_mir_node(
-        tcx,
-        pass_num,
-        pass_name,
-        &node_path,
-        disambiguator,
-        source,
-        body,
-        extra_data,
-    );
+    dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, source, body, extra_data);
 }
 
-pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, source: MirSource<'tcx>) -> bool {
+pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) -> bool {
     let filters = match tcx.sess.opts.debugging_opts.dump_mir {
         None => return false,
         Some(ref filters) => filters,
     };
     let node_path = ty::print::with_forced_impl_filename_line(|| {
         // see notes on #41697 below
-        tcx.def_path_str(source.def_id())
+        tcx.def_path_str(def_id)
     });
     filters.split('|').any(|or_filter| {
         or_filter.split('&').all(|and_filter| {
@@ -117,7 +110,6 @@ fn dump_matched_mir_node<'tcx, F>(
     tcx: TyCtxt<'tcx>,
     pass_num: Option<&dyn Display>,
     pass_name: &str,
-    node_path: &str,
     disambiguator: &dyn Display,
     source: MirSource<'tcx>,
     body: &Body<'tcx>,
@@ -127,14 +119,20 @@ fn dump_matched_mir_node<'tcx, F>(
 {
     let _: io::Result<()> = try {
         let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?;
-        writeln!(file, "// MIR for `{}`", node_path)?;
-        writeln!(file, "// source = {:?}", source)?;
-        writeln!(file, "// pass_name = {}", pass_name)?;
-        writeln!(file, "// disambiguator = {}", disambiguator)?;
+        let def_path = ty::print::with_forced_impl_filename_line(|| {
+            // see notes on #41697 above
+            tcx.def_path_str(source.def_id())
+        });
+        write!(file, "// MIR for `{}", def_path)?;
+        match source.promoted {
+            None => write!(file, "`")?,
+            Some(promoted) => write!(file, "::{:?}`", promoted)?,
+        }
+        writeln!(file, " {} {}", disambiguator, pass_name)?;
         if let Some(ref layout) = body.generator_layout {
             writeln!(file, "// generator_layout = {:?}", layout)?;
         }
-        writeln!(file, "")?;
+        writeln!(file)?;
         extra_data(PassWhere::BeforeCFG, &mut file)?;
         write_user_type_annotations(body, &mut file)?;
         write_mir_fn(tcx, source, body, &mut extra_data, &mut file)?;
@@ -242,13 +240,13 @@ pub fn write_mir_pretty<'tcx>(
             first = false;
         } else {
             // Put empty lines between all items
-            writeln!(w, "")?;
+            writeln!(w)?;
         }
 
         write_mir_fn(tcx, MirSource::item(def_id), body, &mut |_, _| Ok(()), w)?;
 
         for (i, body) in tcx.promoted_mir(def_id).iter_enumerated() {
-            writeln!(w, "")?;
+            writeln!(w)?;
             let src = MirSource { instance: ty::InstanceDef::Item(def_id), promoted: Some(i) };
             write_mir_fn(tcx, src, body, &mut |_, _| Ok(()), w)?;
         }
@@ -271,11 +269,14 @@ where
         extra_data(PassWhere::BeforeBlock(block), w)?;
         write_basic_block(tcx, block, body, extra_data, w)?;
         if block.index() + 1 != body.basic_blocks().len() {
-            writeln!(w, "")?;
+            writeln!(w)?;
         }
     }
 
     writeln!(w, "}}")?;
+
+    write_allocations(tcx, body, w)?;
+
     Ok(())
 }
 
@@ -297,7 +298,7 @@ where
     writeln!(w, "{}{:?}{}: {{", INDENT, block, cleanup_text)?;
 
     // List of statements in the middle.
-    let mut current_location = Location { block: block, statement_index: 0 };
+    let mut current_location = Location { block, statement_index: 0 };
     for statement in &data.statements {
         extra_data(PassWhere::BeforeLocation(current_location), w)?;
         let indented_body = format!("{0}{0}{1:?};", INDENT, statement);
@@ -391,8 +392,8 @@ impl Visitor<'tcx> for ExtraComments<'tcx> {
 
     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
         self.super_rvalue(rvalue, location);
-        match rvalue {
-            Rvalue::Aggregate(kind, _) => match **kind {
+        if let Rvalue::Aggregate(kind, _) = rvalue {
+            match **kind {
                 AggregateKind::Closure(def_id, substs) => {
                     self.push("closure");
                     self.push(&format!("+ def_id: {:?}", def_id));
@@ -412,9 +413,7 @@ impl Visitor<'tcx> for ExtraComments<'tcx> {
                 }
 
                 _ => {}
-            },
-
-            _ => {}
+            }
         }
     }
 }
@@ -490,7 +489,7 @@ fn write_scope_tree(
     }
 
     let children = match scope_tree.get(&parent) {
-        Some(childs) => childs,
+        Some(children) => children,
         None => return Ok(()),
     };
 
@@ -529,7 +528,251 @@ pub fn write_mir_intro<'tcx>(
     write_scope_tree(tcx, body, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1)?;
 
     // Add an empty line before the first block is printed.
-    writeln!(w, "")?;
+    writeln!(w)?;
+
+    Ok(())
+}
+
+/// Find all `AllocId`s mentioned (recursively) in the MIR body and print their corresponding
+/// allocations.
+pub fn write_allocations<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    body: &Body<'_>,
+    w: &mut dyn Write,
+) -> io::Result<()> {
+    fn alloc_ids_from_alloc(alloc: &Allocation) -> impl DoubleEndedIterator<Item = AllocId> + '_ {
+        alloc.relocations().values().map(|(_, id)| *id)
+    }
+    fn alloc_ids_from_const(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
+        match val {
+            ConstValue::Scalar(interpret::Scalar::Ptr(ptr)) => {
+                Either::Left(Either::Left(std::iter::once(ptr.alloc_id)))
+            }
+            ConstValue::Scalar(interpret::Scalar::Raw { .. }) => {
+                Either::Left(Either::Right(std::iter::empty()))
+            }
+            ConstValue::ByRef { alloc, .. } | ConstValue::Slice { data: alloc, .. } => {
+                Either::Right(alloc_ids_from_alloc(alloc))
+            }
+        }
+    }
+    struct CollectAllocIds(BTreeSet<AllocId>);
+    impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds {
+        fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
+            if let ty::ConstKind::Value(val) = c.val {
+                self.0.extend(alloc_ids_from_const(val));
+            }
+            c.super_visit_with(self)
+        }
+    }
+    let mut visitor = CollectAllocIds(Default::default());
+    body.visit_with(&mut visitor);
+    let mut seen = visitor.0;
+    let mut todo: Vec<_> = seen.iter().copied().collect();
+    while let Some(id) = todo.pop() {
+        let mut write_header_and_allocation =
+            |w: &mut dyn Write, alloc: &Allocation| -> io::Result<()> {
+                write!(w, "size: {}, align: {})", alloc.size.bytes(), alloc.align.bytes())?;
+                if alloc.size == Size::ZERO {
+                    write!(w, " {{}}")?;
+                } else {
+                    writeln!(w, " {{")?;
+                    write_allocation(tcx, alloc, w, "    ")?;
+                    write!(w, "}}")?;
+                    // `.rev()` because we are popping them from the back of the `todo` vector.
+                    for id in alloc_ids_from_alloc(alloc).rev() {
+                        if seen.insert(id) {
+                            todo.push(id);
+                        }
+                    }
+                }
+                Ok(())
+            };
+        write!(w, "\n{}", id)?;
+        let alloc = tcx.alloc_map.lock().get(id);
+        match alloc {
+            // This can't really happen unless there are bugs, but it doesn't cost us anything to
+            // gracefully handle it and allow buggy rustc to be debugged via allocation printing.
+            None => write!(w, " (deallocated)")?,
+            Some(GlobalAlloc::Function(inst)) => write!(w, " (fn: {})", inst)?,
+            Some(GlobalAlloc::Static(did)) if !tcx.is_foreign_item(did) => {
+                match tcx.const_eval_poly(did) {
+                    Ok(ConstValue::ByRef { alloc, .. }) => {
+                        write!(w, " (static: {}, ", tcx.def_path_str(did))?;
+                        write_header_and_allocation(w, alloc)?;
+                    }
+                    Ok(_) => {
+                        span_bug!(tcx.def_span(did), " static item without `ByRef` initializer")
+                    }
+                    Err(_) => write!(
+                        w,
+                        " (static: {}, error during initializer evaluation)",
+                        tcx.def_path_str(did)
+                    )?,
+                }
+            }
+            Some(GlobalAlloc::Static(did)) => {
+                write!(w, " (extern static: {})", tcx.def_path_str(did))?
+            }
+            Some(GlobalAlloc::Memory(alloc)) => {
+                write!(w, " (")?;
+                write_header_and_allocation(w, alloc)?
+            }
+        }
+
+        writeln!(w)?;
+    }
+    Ok(())
+}
+
+fn write_allocation_endline(w: &mut dyn Write, ascii: &str) -> io::Result<()> {
+    for _ in 0..(BYTES_PER_LINE - ascii.chars().count()) {
+        write!(w, "   ")?;
+    }
+    writeln!(w, " │ {}", ascii)
+}
+
+/// Number of bytes to print per allocation hex dump line.
+const BYTES_PER_LINE: usize = 16;
+
+/// Prints the line start address and returns the new line start address.
+fn write_allocation_newline(
+    w: &mut dyn Write,
+    mut line_start: Size,
+    ascii: &str,
+    pos_width: usize,
+    prefix: &str,
+) -> io::Result<Size> {
+    write_allocation_endline(w, ascii)?;
+    line_start += Size::from_bytes(BYTES_PER_LINE);
+    write!(w, "{}0x{:02$x} │ ", prefix, line_start.bytes(), pos_width)?;
+    Ok(line_start)
+}
+
+/// Dumps the bytes of an allocation to the given writer. This also prints relocations instead of
+/// the raw bytes where applicable.
+/// The byte format is similar to how hex editors print bytes. Each line starts with the address of
+/// the start of the line, followed by all bytes in hex format (space separated).
+/// If the allocation is small enough to fit into a single line, no start address is given.
+/// After the hex dump, an ascii dump follows, replacing all unprintable characters (control
+/// characters or characters whose value is larger than 127) with a `.`
+///
+/// The `prefix` argument allows callers to add an arbitrary prefix before each line (even if there
+/// is only one line). Note that your prefix should contain a trailing space as the lines are
+/// printed directly after it.
+pub fn write_allocation<Tag, Extra>(
+    tcx: TyCtxt<'tcx>,
+    alloc: &Allocation<Tag, Extra>,
+    w: &mut dyn Write,
+    prefix: &str,
+) -> io::Result<()> {
+    let num_lines = alloc.size.bytes_usize().saturating_sub(BYTES_PER_LINE);
+    // Number of chars needed to represent all line numbers.
+    let pos_width = format!("{:x}", alloc.size.bytes()).len();
+
+    if num_lines > 0 {
+        write!(w, "{}0x{:02$x} │ ", prefix, 0, pos_width)?;
+    } else {
+        write!(w, "{}", prefix)?;
+    }
+
+    let mut i = Size::ZERO;
+    let mut line_start = Size::ZERO;
+
+    let ptr_size = tcx.data_layout.pointer_size;
+
+    let mut ascii = String::new();
+
+    let oversized_ptr = |target: &mut String, width| {
+        if target.len() > width {
+            write!(target, " ({} ptr bytes)", ptr_size.bytes()).unwrap();
+        }
+    };
+
+    while i < alloc.size {
+        // The line start already has a space. While we could remove that space from the line start
+        // printing and unconditionally print a space here, that would cause the single-line case
+        // to have a single space before it, which looks weird.
+        if i != line_start {
+            write!(w, " ")?;
+        }
+        if let Some(&(_, target_id)) = alloc.relocations().get(&i) {
+            // Memory with a relocation must be defined
+            let j = i.bytes_usize();
+            let offset =
+                alloc.inspect_with_undef_and_ptr_outside_interpreter(j..j + ptr_size.bytes_usize());
+            let offset = read_target_uint(tcx.data_layout.endian, offset).unwrap();
+            let relocation_width = |bytes| bytes * 3;
+            let mut target = format!("{}+{}", target_id, offset);
+            if ((i - line_start) + ptr_size).bytes_usize() > BYTES_PER_LINE {
+                // This branch handles the situation where a relocation starts in the current line
+                // but ends in the next one.
+                let remainder = Size::from_bytes(BYTES_PER_LINE) - (i - line_start);
+                let overflow = ptr_size - remainder;
+                let remainder_width = relocation_width(remainder.bytes_usize()) - 2;
+                let overflow_width = relocation_width(overflow.bytes_usize() - 1) + 1;
+                ascii.push('╾');
+                for _ in 0..remainder.bytes() - 1 {
+                    ascii.push('─');
+                }
+                if overflow_width > remainder_width && overflow_width >= target.len() {
+                    // The case where the relocation fits into the part in the next line
+                    write!(w, "╾{0:─^1$}", "", remainder_width)?;
+                    line_start =
+                        write_allocation_newline(w, line_start, &ascii, pos_width, prefix)?;
+                    ascii.clear();
+                    write!(w, "{0:─^1$}╼", target, overflow_width)?;
+                } else {
+                    oversized_ptr(&mut target, remainder_width);
+                    write!(w, "╾{0:─^1$}", target, remainder_width)?;
+                    line_start =
+                        write_allocation_newline(w, line_start, &ascii, pos_width, prefix)?;
+                    write!(w, "{0:─^1$}╼", "", overflow_width)?;
+                    ascii.clear();
+                }
+                for _ in 0..overflow.bytes() - 1 {
+                    ascii.push('─');
+                }
+                ascii.push('╼');
+                i += ptr_size;
+                continue;
+            } else {
+                // This branch handles a relocation that starts and ends in the current line.
+                let relocation_width = relocation_width(ptr_size.bytes_usize() - 1);
+                oversized_ptr(&mut target, relocation_width);
+                ascii.push('╾');
+                write!(w, "╾{0:─^1$}╼", target, relocation_width)?;
+                for _ in 0..ptr_size.bytes() - 2 {
+                    ascii.push('─');
+                }
+                ascii.push('╼');
+                i += ptr_size;
+            }
+        } else if alloc.undef_mask().is_range_defined(i, i + Size::from_bytes(1)).is_ok() {
+            let j = i.bytes_usize();
+
+            // Checked definedness (and thus range) and relocations. This access also doesn't
+            // influence interpreter execution but is only for debugging.
+            let c = alloc.inspect_with_undef_and_ptr_outside_interpreter(j..j + 1)[0];
+            write!(w, "{:02x}", c)?;
+            if c.is_ascii_control() || c >= 0x80 {
+                ascii.push('.');
+            } else {
+                ascii.push(char::from(c));
+            }
+            i += Size::from_bytes(1);
+        } else {
+            write!(w, "__")?;
+            ascii.push('░');
+            i += Size::from_bytes(1);
+        }
+        // Print a new line header if the next line still has some bytes to print.
+        if i == line_start + Size::from_bytes(BYTES_PER_LINE) && i != alloc.size {
+            line_start = write_allocation_newline(w, line_start, &ascii, pos_width, prefix)?;
+            ascii.clear();
+        }
+    }
+    write_allocation_endline(w, &ascii)?;
 
     Ok(())
 }
@@ -545,7 +788,7 @@ fn write_mir_sig(
     trace!("write_mir_sig: {:?}", src.instance);
     let kind = tcx.def_kind(src.def_id());
     let is_function = match kind {
-        Some(DefKind::Fn) | Some(DefKind::Method) | Some(DefKind::Ctor(..)) => true,
+        Some(DefKind::Fn) | Some(DefKind::AssocFn) | Some(DefKind::Ctor(..)) => true,
         _ => tcx.is_closure(src.def_id()),
     };
     match (kind, src.promoted) {
@@ -561,7 +804,7 @@ fn write_mir_sig(
 
     ty::print::with_forced_impl_filename_line(|| {
         // see notes on #41697 elsewhere
-        write!(w, " {}", tcx.def_path_str(src.def_id()))
+        write!(w, "{}", tcx.def_path_str(src.def_id()))
     })?;
 
     if src.promoted.is_none() && is_function {