about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-04-01 14:21:31 +0000
committerbors <bors@rust-lang.org>2020-04-01 14:21:31 +0000
commit235938d1acdd93d6641a741c81f64e415b786751 (patch)
tree175a4a3534196b2226fe3978dc7b9953f4ab30d7 /src
parent99009bf31992fb9257b84550dbf7cb509f987952 (diff)
parentc1419b4c919fcdb91205b32a6ccca7b170b1e58a (diff)
Auto merge of #70653 - Centril:rollup-vh5x5e5, r=Centril
Rollup of 6 pull requests

Successful merges:

 - #70511 (Add `-Z dump-mir-dataflow` flag for dumping dataflow results visualization)
 - #70522 (Improve error messages for raw strings (#60762))
 - #70547 (Add `can_unwind` field to `FnAbi`)
 - #70591 (Ensure LLVM is in the link path for "fulldeps" tests)
 - #70627 (Use place directly its copy)
 - #70652 (Add git repo address to unstable book)

Failed merges:

 - #70634 (Remove some reexports in `rustc_middle`)

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/test.rs11
-rw-r--r--src/doc/unstable-book/book.toml3
-rw-r--r--src/librustc_codegen_llvm/abi.rs7
-rw-r--r--src/librustc_codegen_llvm/attributes.rs58
-rw-r--r--src/librustc_codegen_llvm/callee.rs2
-rw-r--r--src/librustc_codegen_llvm/mono_item.rs2
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs12
-rw-r--r--src/librustc_codegen_ssa/mir/rvalue.rs10
-rw-r--r--src/librustc_interface/tests.rs2
-rw-r--r--src/librustc_lexer/src/lib.rs146
-rw-r--r--src/librustc_lexer/src/tests.rs121
-rw-r--r--src/librustc_middle/mir/mod.rs4
-rw-r--r--src/librustc_middle/ty/layout.rs60
-rw-r--r--src/librustc_mir/borrow_check/borrow_set.rs2
-rw-r--r--src/librustc_mir/borrow_check/constraint_generation.rs8
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs57
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs2
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/move_errors.rs28
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs2
-rw-r--r--src/librustc_mir/borrow_check/invalidation.rs56
-rw-r--r--src/librustc_mir/borrow_check/mod.rs68
-rw-r--r--src/librustc_mir/borrow_check/nll.rs2
-rw-r--r--src/librustc_mir/borrow_check/path_utils.rs6
-rw-r--r--src/librustc_mir/borrow_check/places_conflict.rs8
-rw-r--r--src/librustc_mir/borrow_check/used_muts.rs8
-rw-r--r--src/librustc_mir/dataflow/drop_flag_effects.rs4
-rw-r--r--src/librustc_mir/dataflow/framework/cursor.rs4
-rw-r--r--src/librustc_mir/dataflow/framework/engine.rs35
-rw-r--r--src/librustc_mir/dataflow/framework/mod.rs18
-rw-r--r--src/librustc_mir/dataflow/framework/tests.rs2
-rw-r--r--src/librustc_mir/dataflow/impls/borrowed_locals.rs20
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs14
-rw-r--r--src/librustc_mir/dataflow/impls/mod.rs10
-rw-r--r--src/librustc_mir/dataflow/impls/storage_liveness.rs6
-rw-r--r--src/librustc_mir/dataflow/move_paths/builder.rs38
-rw-r--r--src/librustc_mir/interpret/operand.rs4
-rw-r--r--src/librustc_mir/interpret/place.rs2
-rw-r--r--src/librustc_mir/interpret/step.rs28
-rw-r--r--src/librustc_mir/interpret/terminator.rs10
-rw-r--r--src/librustc_mir/shim.rs2
-rw-r--r--src/librustc_mir/transform/add_moves_for_packed_drops.rs2
-rw-r--r--src/librustc_mir/transform/check_consts/resolver.rs6
-rw-r--r--src/librustc_mir/transform/check_consts/validation.rs6
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs6
-rw-r--r--src/librustc_mir/transform/const_prop.rs8
-rw-r--r--src/librustc_mir/transform/copy_prop.rs7
-rw-r--r--src/librustc_mir/transform/dump_mir.rs2
-rw-r--r--src/librustc_mir/transform/elaborate_drops.rs10
-rw-r--r--src/librustc_mir/transform/generator.rs2
-rw-r--r--src/librustc_mir/transform/inline.rs4
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs18
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs8
-rw-r--r--src/librustc_mir/transform/simplify_try.rs6
-rw-r--r--src/librustc_mir/util/alignment.rs4
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs73
-rw-r--r--src/librustc_mir/util/liveness.rs2
-rw-r--r--src/librustc_mir/util/pretty.rs6
-rw-r--r--src/librustc_mir_build/build/block.rs4
-rw-r--r--src/librustc_mir_build/build/cfg.rs8
-rw-r--r--src/librustc_mir_build/build/expr/as_place.rs6
-rw-r--r--src/librustc_mir_build/build/expr/as_rvalue.rs23
-rw-r--r--src/librustc_mir_build/build/expr/as_temp.rs2
-rw-r--r--src/librustc_mir_build/build/expr/into.rs17
-rw-r--r--src/librustc_mir_build/build/expr/stmt.rs4
-rw-r--r--src/librustc_mir_build/build/into.rs8
-rw-r--r--src/librustc_mir_build/build/matches/mod.rs26
-rw-r--r--src/librustc_mir_build/build/matches/test.rs10
-rw-r--r--src/librustc_mir_build/build/misc.rs2
-rw-r--r--src/librustc_mir_build/build/mod.rs4
-rw-r--r--src/librustc_mir_build/build/scope.rs4
-rw-r--r--src/librustc_parse/lexer/mod.rs93
-rw-r--r--src/librustc_parse/lib.rs1
-rw-r--r--src/librustc_parse/parser/diagnostics.rs33
-rw-r--r--src/librustc_session/options.rs2
-rw-r--r--src/librustc_target/abi/call/mod.rs2
-rw-r--r--src/test/ui/parser/raw-str-unbalanced.rs4
-rw-r--r--src/test/ui/parser/raw-str-unbalanced.stderr8
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-eof.rs (renamed from src/test/ui/parser/raw-byte-string-eof.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-eof.stderr (renamed from src/test/ui/parser/raw-byte-string-eof.stderr)4
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-literals.rs (renamed from src/test/ui/parser/raw-byte-string-literals.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-byte-string-literals.stderr (renamed from src/test/ui/parser/raw-byte-string-literals.stderr)0
-rw-r--r--src/test/ui/parser/raw/raw-str-delim.rs (renamed from src/test/ui/parser/raw-str-delim.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-str-delim.stderr (renamed from src/test/ui/parser/raw-str-delim.stderr)0
-rw-r--r--src/test/ui/parser/raw/raw-str-in-macro-call.rs14
-rw-r--r--src/test/ui/parser/raw/raw-str-unbalanced.rs4
-rw-r--r--src/test/ui/parser/raw/raw-str-unbalanced.stderr10
-rw-r--r--src/test/ui/parser/raw/raw-str-unterminated.rs (renamed from src/test/ui/parser/raw-str-unterminated.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-str-unterminated.stderr (renamed from src/test/ui/parser/raw-str-unterminated.stderr)0
-rw-r--r--src/test/ui/parser/raw/raw-string-2.rs4
-rw-r--r--src/test/ui/parser/raw/raw-string-2.stderr11
-rw-r--r--src/test/ui/parser/raw/raw-string.rs (renamed from src/test/ui/parser/raw/raw_string.rs)0
-rw-r--r--src/test/ui/parser/raw/raw-string.stderr (renamed from src/test/ui/parser/raw/raw_string.stderr)6
92 files changed, 852 insertions, 514 deletions
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 5b946b05735..2499856235f 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -21,7 +21,7 @@ use crate::flags::Subcommand;
 use crate::native;
 use crate::tool::{self, SourceType, Tool};
 use crate::toolstate::ToolState;
-use crate::util::{self, dylib_path, dylib_path_var};
+use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var};
 use crate::Crate as CargoCrate;
 use crate::{envify, DocTests, GitRepo, Mode};
 
@@ -1178,6 +1178,15 @@ impl Step for Compiletest {
                 cmd.arg("--system-llvm");
             }
 
+            // Tests that use compiler libraries may inherit the `-lLLVM` link
+            // requirement, but the `-L` library path is not propagated across
+            // separate compilations. We can add LLVM's library path to the
+            // platform-specific environment variable as a workaround.
+            if !builder.config.dry_run && suite.ends_with("fulldeps") {
+                let llvm_libdir = output(Command::new(&llvm_config).arg("--libdir"));
+                add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd);
+            }
+
             // Only pass correct values for these flags for the `run-make` suite as it
             // requires that a C++ compiler was configured which isn't always the case.
             if !builder.config.dry_run && suite == "run-make-fulldeps" {
diff --git a/src/doc/unstable-book/book.toml b/src/doc/unstable-book/book.toml
index 5b2e19bd7aa..0cd56d09404 100644
--- a/src/doc/unstable-book/book.toml
+++ b/src/doc/unstable-book/book.toml
@@ -1,3 +1,6 @@
 [book]
 title = "The Rust Unstable Book"
 author = "The Rust Community"
+
+[output.html]
+git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/unstable-book"
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index 38dd879de7d..064ca53bd1b 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -396,6 +396,11 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
             llvm::Attribute::NoReturn.apply_llfn(llvm::AttributePlace::Function, llfn);
         }
 
+        // FIXME(eddyb, wesleywiser): apply this to callsites as well?
+        if !self.can_unwind {
+            llvm::Attribute::NoUnwind.apply_llfn(llvm::AttributePlace::Function, llfn);
+        }
+
         let mut i = 0;
         let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
             attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn, ty);
@@ -431,6 +436,8 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
     }
 
     fn apply_attrs_callsite(&self, bx: &mut Builder<'a, 'll, 'tcx>, callsite: &'ll Value) {
+        // FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
+
         let mut i = 0;
         let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
             attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite, ty);
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index e4d6d7d8af9..784a3a87e98 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -10,13 +10,10 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::config::{OptLevel, Sanitizer};
 use rustc_session::Session;
-use rustc_target::abi::call::Conv;
-use rustc_target::spec::PanicStrategy;
 
-use crate::abi::FnAbi;
 use crate::attributes;
 use crate::llvm::AttributePlace::Function;
 use crate::llvm::{self, Attribute};
@@ -77,12 +74,6 @@ pub fn emit_uwtable(val: &'ll Value, emit: bool) {
     Attribute::UWTable.toggle_llfn(Function, val, emit);
 }
 
-/// Tell LLVM whether the function can or cannot unwind.
-#[inline]
-fn unwind(val: &'ll Value, can_unwind: bool) {
-    Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind);
-}
-
 /// Tell LLVM if this function should be 'naked', i.e., skip the epilogue and prologue.
 #[inline]
 fn naked(val: &'ll Value, is_naked: bool) {
@@ -246,12 +237,7 @@ pub(crate) fn default_optimisation_attrs(sess: &Session, llfn: &'ll Value) {
 
 /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
 /// attributes.
-pub fn from_fn_attrs(
-    cx: &CodegenCx<'ll, 'tcx>,
-    llfn: &'ll Value,
-    instance: ty::Instance<'tcx>,
-    fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
-) {
+pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::Instance<'tcx>) {
     let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
 
     match codegen_fn_attrs.optimize {
@@ -315,46 +301,6 @@ pub fn from_fn_attrs(
     }
     sanitize(cx, codegen_fn_attrs.flags, llfn);
 
-    unwind(
-        llfn,
-        if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind {
-            // In panic=abort mode we assume nothing can unwind anywhere, so
-            // optimize based on this!
-            false
-        } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
-            // If a specific #[unwind] attribute is present, use that.
-            true
-        } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
-            // Special attribute for allocator functions, which can't unwind.
-            false
-        } else {
-            if fn_abi.conv == Conv::Rust {
-                // Any Rust method (or `extern "Rust" fn` or `extern
-                // "rust-call" fn`) is explicitly allowed to unwind
-                // (unless it has no-unwind attribute, handled above).
-                true
-            } else {
-                // Anything else is either:
-                //
-                //  1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or
-                //
-                //  2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`).
-                //
-                // Foreign items (case 1) are assumed to not unwind; it is
-                // UB otherwise. (At least for now; see also
-                // rust-lang/rust#63909 and Rust RFC 2753.)
-                //
-                // Items defined in Rust with non-Rust ABIs (case 2) are also
-                // not supposed to unwind. Whether this should be enforced
-                // (versus stating it is UB) and *how* it would be enforced
-                // is currently under discussion; see rust-lang/rust#58794.
-                //
-                // In either case, we mark item as explicitly nounwind.
-                false
-            }
-        },
-    );
-
     // Always annotate functions with the target-cpu they are compiled for.
     // Without this, ThinLTO won't inline Rust functions into Clang generated
     // functions (because Clang annotates functions this way too).
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 0759823c07a..a36314448b1 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -78,7 +78,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
         let llfn = cx.declare_fn(&sym, &fn_abi);
         debug!("get_fn: not casting pointer!");
 
-        attributes::from_fn_attrs(cx, llfn, instance, &fn_abi);
+        attributes::from_fn_attrs(cx, llfn, instance);
 
         let instance_def_id = instance.def_id();
 
diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs
index fe1537fbd02..a7a9d0c8a07 100644
--- a/src/librustc_codegen_llvm/mono_item.rs
+++ b/src/librustc_codegen_llvm/mono_item.rs
@@ -77,7 +77,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
 
         debug!("predefine_fn: instance = {:?}", instance);
 
-        attributes::from_fn_attrs(self, lldecl, instance, &fn_abi);
+        attributes::from_fn_attrs(self, lldecl, instance);
 
         self.instances.borrow_mut().insert(instance, lldecl);
     }
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index e71a63b7f30..931fab6ae01 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -299,7 +299,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         &mut self,
         helper: TerminatorCodegenHelper<'tcx>,
         mut bx: Bx,
-        location: &mir::Place<'tcx>,
+        location: mir::Place<'tcx>,
         target: mir::BasicBlock,
         unwind: Option<mir::BasicBlock>,
     ) {
@@ -580,7 +580,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         if intrinsic == Some("transmute") {
             if let Some(destination_ref) = destination.as_ref() {
-                let &(ref dest, target) = destination_ref;
+                let &(dest, target) = destination_ref;
                 self.codegen_transmute(&mut bx, &args[0], dest);
                 helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
                 helper.funclet_br(self, &mut bx, target);
@@ -619,7 +619,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let mut llargs = Vec::with_capacity(arg_count);
 
         // Prepare the return value destination
-        let ret_dest = if let Some((ref dest, _)) = *destination {
+        let ret_dest = if let Some((dest, _)) = *destination {
             let is_intrinsic = intrinsic.is_some();
             self.make_return_dest(&mut bx, dest, &fn_abi.ret, &mut llargs, is_intrinsic)
         } else {
@@ -873,7 +873,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 bx.unreachable();
             }
 
-            mir::TerminatorKind::Drop { ref location, target, unwind } => {
+            mir::TerminatorKind::Drop { location, target, unwind } => {
                 self.codegen_drop_terminator(helper, bx, location, target, unwind);
             }
 
@@ -1123,7 +1123,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     fn make_return_dest(
         &mut self,
         bx: &mut Bx,
-        dest: &mir::Place<'tcx>,
+        dest: mir::Place<'tcx>,
         fn_ret: &ArgAbi<'tcx, Ty<'tcx>>,
         llargs: &mut Vec<Bx::Value>,
         is_intrinsic: bool,
@@ -1184,7 +1184,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    fn codegen_transmute(&mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, dst: &mir::Place<'tcx>) {
+    fn codegen_transmute(&mut self, bx: &mut Bx, src: &mir::Operand<'tcx>, dst: mir::Place<'tcx>) {
         if let Some(index) = dst.as_local() {
             match self.locals[index] {
                 LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 66ce50c482a..ce681c729b2 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -383,7 +383,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 (bx, OperandRef { val, layout: cast })
             }
 
-            mir::Rvalue::Ref(_, bk, ref place) => {
+            mir::Rvalue::Ref(_, bk, place) => {
                 let mk_ref = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| {
                     tcx.mk_ref(
                         tcx.lifetimes.re_erased,
@@ -393,14 +393,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 self.codegen_place_to_pointer(bx, place, mk_ref)
             }
 
-            mir::Rvalue::AddressOf(mutability, ref place) => {
+            mir::Rvalue::AddressOf(mutability, place) => {
                 let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| {
                     tcx.mk_ptr(ty::TypeAndMut { ty, mutbl: mutability })
                 };
                 self.codegen_place_to_pointer(bx, place, mk_ptr)
             }
 
-            mir::Rvalue::Len(ref place) => {
+            mir::Rvalue::Len(place) => {
                 let size = self.evaluate_array_len(&mut bx, place);
                 let operand = OperandRef {
                     val: OperandValue::Immediate(size),
@@ -537,7 +537,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    fn evaluate_array_len(&mut self, bx: &mut Bx, place: &mir::Place<'tcx>) -> Bx::Value {
+    fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value {
         // ZST are passed as operands and require special handling
         // because codegen_place() panics if Local is operand.
         if let Some(index) = place.as_local() {
@@ -557,7 +557,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     fn codegen_place_to_pointer(
         &mut self,
         mut bx: Bx,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
         mk_ptr_ty: impl FnOnce(TyCtxt<'tcx>, Ty<'tcx>) -> Ty<'tcx>,
     ) -> (Bx, OperandRef<'tcx, Bx::Value>) {
         let cg_place = self.codegen_place(&mut bx, place.as_ref());
diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs
index a9d9052423c..f58c5cc8eeb 100644
--- a/src/librustc_interface/tests.rs
+++ b/src/librustc_interface/tests.rs
@@ -562,6 +562,8 @@ fn test_debugging_options_tracking_hash() {
     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
     opts.debugging_opts.dump_mir_graphviz = true;
     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
+    opts.debugging_opts.dump_mir_dataflow = true;
+    assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
 
     // Make sure changing a [TRACKED] option changes the hash
     opts = reference.clone();
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index d3ac58a49c8..fcb7475cc2e 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -17,9 +17,13 @@
 mod cursor;
 pub mod unescape;
 
+#[cfg(test)]
+mod tests;
+
 use self::LiteralKind::*;
 use self::TokenKind::*;
 use crate::cursor::{Cursor, EOF_CHAR};
+use std::convert::TryInto;
 
 /// Parsed token.
 /// It doesn't contain information about data that has been parsed,
@@ -132,9 +136,80 @@ pub enum LiteralKind {
     /// "b"abc"", "b"abc"
     ByteStr { terminated: bool },
     /// "r"abc"", "r#"abc"#", "r####"ab"###"c"####", "r#"a"
-    RawStr { n_hashes: usize, started: bool, terminated: bool },
+    RawStr(UnvalidatedRawStr),
     /// "br"abc"", "br#"abc"#", "br####"ab"###"c"####", "br#"a"
-    RawByteStr { n_hashes: usize, started: bool, terminated: bool },
+    RawByteStr(UnvalidatedRawStr),
+}
+
+/// Represents something that looks like a raw string, but may have some
+/// problems. Use `.validate()` to convert it into something
+/// usable.
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct UnvalidatedRawStr {
+    /// The prefix (`r###"`) is valid
+    valid_start: bool,
+    /// The number of leading `#`
+    n_start_hashes: usize,
+    /// The number of trailing `#`. `n_end_hashes` <= `n_start_hashes`
+    n_end_hashes: usize,
+    /// The offset starting at `r` or `br` where the user may have intended to end the string.
+    /// Currently, it is the longest sequence of pattern `"#+"`.
+    possible_terminator_offset: Option<usize>,
+}
+
+/// Error produced validating a raw string. Represents cases like:
+/// - `r##~"abcde"##`: `LexRawStrError::InvalidStarter`
+/// - `r###"abcde"##`: `LexRawStrError::NoTerminator { expected: 3, found: 2, possible_terminator_offset: Some(11)`
+/// - Too many `#`s (>65536): `TooManyDelimiters`
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub enum LexRawStrError {
+    /// Non `#` characters exist between `r` and `"` eg. `r#~"..`
+    InvalidStarter,
+    /// The string was never terminated. `possible_terminator_offset` is the number of characters after `r` or `br` where they
+    /// may have intended to terminate it.
+    NoTerminator { expected: usize, found: usize, possible_terminator_offset: Option<usize> },
+    /// More than 65536 `#`s exist.
+    TooManyDelimiters,
+}
+
+/// Raw String that contains a valid prefix (`#+"`) and postfix (`"#+`) where
+/// there are a matching number of `#` characters in both. Note that this will
+/// not consume extra trailing `#` characters: `r###"abcde"####` is lexed as a
+/// `ValidatedRawString { n_hashes: 3 }` followed by a `#` token.
+#[derive(Debug, Eq, PartialEq, Copy, Clone)]
+pub struct ValidatedRawStr {
+    n_hashes: u16,
+}
+
+impl ValidatedRawStr {
+    pub fn num_hashes(&self) -> u16 {
+        self.n_hashes
+    }
+}
+
+impl UnvalidatedRawStr {
+    pub fn validate(self) -> Result<ValidatedRawStr, LexRawStrError> {
+        if !self.valid_start {
+            return Err(LexRawStrError::InvalidStarter);
+        }
+
+        // Only up to 65535 `#`s are allowed in raw strings
+        let n_start_safe: u16 =
+            self.n_start_hashes.try_into().map_err(|_| LexRawStrError::TooManyDelimiters)?;
+
+        if self.n_start_hashes > self.n_end_hashes {
+            Err(LexRawStrError::NoTerminator {
+                expected: self.n_start_hashes,
+                found: self.n_end_hashes,
+                possible_terminator_offset: self.possible_terminator_offset,
+            })
+        } else {
+            // Since the lexer should never produce a literal with n_end > n_start, if n_start <= n_end,
+            // they must be equal.
+            debug_assert_eq!(self.n_start_hashes, self.n_end_hashes);
+            Ok(ValidatedRawStr { n_hashes: n_start_safe })
+        }
+    }
 }
 
 /// Base of numeric literal encoding according to its prefix.
@@ -209,7 +284,7 @@ pub fn is_whitespace(c: char) -> bool {
         // Dedicated whitespace characters from Unicode
         | '\u{2028}' // LINE SEPARATOR
         | '\u{2029}' // PARAGRAPH SEPARATOR
-            => true,
+        => true,
         _ => false,
     }
 }
@@ -258,12 +333,12 @@ impl Cursor<'_> {
             'r' => match (self.first(), self.second()) {
                 ('#', c1) if is_id_start(c1) => self.raw_ident(),
                 ('#', _) | ('"', _) => {
-                    let (n_hashes, started, terminated) = self.raw_double_quoted_string();
+                    let raw_str_i = self.raw_double_quoted_string(1);
                     let suffix_start = self.len_consumed();
-                    if terminated {
+                    if raw_str_i.n_end_hashes == raw_str_i.n_start_hashes {
                         self.eat_literal_suffix();
                     }
-                    let kind = RawStr { n_hashes, started, terminated };
+                    let kind = RawStr(raw_str_i);
                     Literal { kind, suffix_start }
                 }
                 _ => self.ident(),
@@ -293,12 +368,14 @@ impl Cursor<'_> {
                 }
                 ('r', '"') | ('r', '#') => {
                     self.bump();
-                    let (n_hashes, started, terminated) = self.raw_double_quoted_string();
+                    let raw_str_i = self.raw_double_quoted_string(2);
                     let suffix_start = self.len_consumed();
+                    let terminated = raw_str_i.n_start_hashes == raw_str_i.n_end_hashes;
                     if terminated {
                         self.eat_literal_suffix();
                     }
-                    let kind = RawByteStr { n_hashes, started, terminated };
+
+                    let kind = RawByteStr(raw_str_i);
                     Literal { kind, suffix_start }
                 }
                 _ => self.ident(),
@@ -594,29 +671,41 @@ impl Cursor<'_> {
         false
     }
 
-    /// Eats the double-quoted string and returns a tuple of
-    /// (amount of the '#' symbols, raw string started, raw string terminated)
-    fn raw_double_quoted_string(&mut self) -> (usize, bool, bool) {
+    /// Eats the double-quoted string and returns an `UnvalidatedRawStr`.
+    fn raw_double_quoted_string(&mut self, prefix_len: usize) -> UnvalidatedRawStr {
         debug_assert!(self.prev() == 'r');
-        let mut started: bool = false;
-        let mut finished: bool = false;
+        let mut valid_start: bool = false;
+        let start_pos = self.len_consumed();
+        let (mut possible_terminator_offset, mut max_hashes) = (None, 0);
 
         // Count opening '#' symbols.
-        let n_hashes = self.eat_while(|c| c == '#');
+        let n_start_hashes = self.eat_while(|c| c == '#');
 
         // Check that string is started.
         match self.bump() {
-            Some('"') => started = true,
-            _ => return (n_hashes, started, finished),
+            Some('"') => valid_start = true,
+            _ => {
+                return UnvalidatedRawStr {
+                    valid_start,
+                    n_start_hashes,
+                    n_end_hashes: 0,
+                    possible_terminator_offset,
+                };
+            }
         }
 
         // Skip the string contents and on each '#' character met, check if this is
         // a raw string termination.
-        while !finished {
+        loop {
             self.eat_while(|c| c != '"');
 
             if self.is_eof() {
-                return (n_hashes, started, finished);
+                return UnvalidatedRawStr {
+                    valid_start,
+                    n_start_hashes,
+                    n_end_hashes: max_hashes,
+                    possible_terminator_offset,
+                };
             }
 
             // Eat closing double quote.
@@ -624,7 +713,7 @@ impl Cursor<'_> {
 
             // Check that amount of closing '#' symbols
             // is equal to the amount of opening ones.
-            let mut hashes_left = n_hashes;
+            let mut hashes_left = n_start_hashes;
             let is_closing_hash = |c| {
                 if c == '#' && hashes_left != 0 {
                     hashes_left -= 1;
@@ -633,10 +722,23 @@ impl Cursor<'_> {
                     false
                 }
             };
-            finished = self.eat_while(is_closing_hash) == n_hashes;
+            let n_end_hashes = self.eat_while(is_closing_hash);
+
+            if n_end_hashes == n_start_hashes {
+                return UnvalidatedRawStr {
+                    valid_start,
+                    n_start_hashes,
+                    n_end_hashes,
+                    possible_terminator_offset: None,
+                };
+            } else if n_end_hashes > max_hashes {
+                // Keep track of possible terminators to give a hint about where there might be
+                // a missing terminator
+                possible_terminator_offset =
+                    Some(self.len_consumed() - start_pos - n_end_hashes + prefix_len);
+                max_hashes = n_end_hashes;
+            }
         }
-
-        (n_hashes, started, finished)
     }
 
     fn eat_decimal_digits(&mut self) -> bool {
diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs
new file mode 100644
index 00000000000..4af435536f0
--- /dev/null
+++ b/src/librustc_lexer/src/tests.rs
@@ -0,0 +1,121 @@
+#[cfg(test)]
+mod tests {
+    use crate::*;
+
+    fn check_raw_str(
+        s: &str,
+        expected: UnvalidatedRawStr,
+        validated: Result<ValidatedRawStr, LexRawStrError>,
+    ) {
+        let s = &format!("r{}", s);
+        let mut cursor = Cursor::new(s);
+        cursor.bump();
+        let tok = cursor.raw_double_quoted_string(0);
+        assert_eq!(tok, expected);
+        assert_eq!(tok.validate(), validated);
+    }
+
+    #[test]
+    fn test_naked_raw_str() {
+        check_raw_str(
+            r#""abc""#,
+            UnvalidatedRawStr {
+                n_start_hashes: 0,
+                n_end_hashes: 0,
+                valid_start: true,
+                possible_terminator_offset: None,
+            },
+            Ok(ValidatedRawStr { n_hashes: 0 }),
+        );
+    }
+
+    #[test]
+    fn test_raw_no_start() {
+        check_raw_str(
+            r##""abc"#"##,
+            UnvalidatedRawStr {
+                n_start_hashes: 0,
+                n_end_hashes: 0,
+                valid_start: true,
+                possible_terminator_offset: None,
+            },
+            Ok(ValidatedRawStr { n_hashes: 0 }),
+        );
+    }
+
+    #[test]
+    fn test_too_many_terminators() {
+        // this error is handled in the parser later
+        check_raw_str(
+            r###"#"abc"##"###,
+            UnvalidatedRawStr {
+                n_start_hashes: 1,
+                n_end_hashes: 1,
+                valid_start: true,
+                possible_terminator_offset: None,
+            },
+            Ok(ValidatedRawStr { n_hashes: 1 }),
+        );
+    }
+
+    #[test]
+    fn test_unterminated() {
+        check_raw_str(
+            r#"#"abc"#,
+            UnvalidatedRawStr {
+                n_start_hashes: 1,
+                n_end_hashes: 0,
+                valid_start: true,
+                possible_terminator_offset: None,
+            },
+            Err(LexRawStrError::NoTerminator {
+                expected: 1,
+                found: 0,
+                possible_terminator_offset: None,
+            }),
+        );
+        check_raw_str(
+            r###"##"abc"#"###,
+            UnvalidatedRawStr {
+                n_start_hashes: 2,
+                n_end_hashes: 1,
+                valid_start: true,
+                possible_terminator_offset: Some(7),
+            },
+            Err(LexRawStrError::NoTerminator {
+                expected: 2,
+                found: 1,
+                possible_terminator_offset: Some(7),
+            }),
+        );
+        // We're looking for "# not just any #
+        check_raw_str(
+            r###"##"abc#"###,
+            UnvalidatedRawStr {
+                n_start_hashes: 2,
+                n_end_hashes: 0,
+                valid_start: true,
+                possible_terminator_offset: None,
+            },
+            Err(LexRawStrError::NoTerminator {
+                expected: 2,
+                found: 0,
+                possible_terminator_offset: None,
+            }),
+        )
+    }
+
+    #[test]
+    fn test_invalid_start() {
+        check_raw_str(
+            r##"#~"abc"#"##,
+            UnvalidatedRawStr {
+                n_start_hashes: 1,
+                n_end_hashes: 0,
+                valid_start: false,
+                possible_terminator_offset: None,
+            },
+            Err(LexRawStrError::InvalidStarter),
+        );
+    }
+}
diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs
index 9ba9d816d0f..216fe43e819 100644
--- a/src/librustc_middle/mir/mod.rs
+++ b/src/librustc_middle/mir/mod.rs
@@ -2030,9 +2030,9 @@ impl<'tcx> Operand<'tcx> {
 
     /// Returns the `Place` that is the target of this `Operand`, or `None` if this `Operand` is a
     /// constant.
-    pub fn place(&self) -> Option<&Place<'tcx>> {
+    pub fn place(&self) -> Option<Place<'tcx>> {
         match self {
-            Operand::Copy(place) | Operand::Move(place) => Some(place),
+            Operand::Copy(place) | Operand::Move(place) => Some(*place),
             Operand::Constant(_) => None,
         }
     }
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index 54fde52ba3a..17c93922b00 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -1,4 +1,5 @@
 use crate::ich::StableHashingContext;
+use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
 use crate::ty::subst::Subst;
 use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
@@ -15,7 +16,7 @@ use rustc_target::abi::call::{
     ArgAbi, ArgAttribute, ArgAttributes, Conv, FnAbi, PassMode, Reg, RegKind,
 };
 pub use rustc_target::abi::*;
-use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec};
+use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy};
 
 use std::cmp;
 use std::fmt;
@@ -2368,11 +2369,55 @@ where
         sig: ty::PolyFnSig<'tcx>,
         extra_args: &[Ty<'tcx>],
         caller_location: Option<Ty<'tcx>>,
+        codegen_fn_attr_flags: CodegenFnAttrFlags,
         mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
     ) -> Self;
     fn adjust_for_abi(&mut self, cx: &C, abi: SpecAbi);
 }
 
+fn fn_can_unwind(
+    panic_strategy: PanicStrategy,
+    codegen_fn_attr_flags: CodegenFnAttrFlags,
+    call_conv: Conv,
+) -> bool {
+    if panic_strategy != PanicStrategy::Unwind {
+        // In panic=abort mode we assume nothing can unwind anywhere, so
+        // optimize based on this!
+        false
+    } else if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::UNWIND) {
+        // If a specific #[unwind] attribute is present, use that.
+        true
+    } else if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
+        // Special attribute for allocator functions, which can't unwind.
+        false
+    } else {
+        if call_conv == Conv::Rust {
+            // Any Rust method (or `extern "Rust" fn` or `extern
+            // "rust-call" fn`) is explicitly allowed to unwind
+            // (unless it has no-unwind attribute, handled above).
+            true
+        } else {
+            // Anything else is either:
+            //
+            //  1. A foreign item using a non-Rust ABI (like `extern "C" { fn foo(); }`), or
+            //
+            //  2. A Rust item using a non-Rust ABI (like `extern "C" fn foo() { ... }`).
+            //
+            // Foreign items (case 1) are assumed to not unwind; it is
+            // UB otherwise. (At least for now; see also
+            // rust-lang/rust#63909 and Rust RFC 2753.)
+            //
+            // Items defined in Rust with non-Rust ABIs (case 2) are also
+            // not supposed to unwind. Whether this should be enforced
+            // (versus stating it is UB) and *how* it would be enforced
+            // is currently under discussion; see rust-lang/rust#58794.
+            //
+            // In either case, we mark item as explicitly nounwind.
+            false
+        }
+    }
+}
+
 impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>>
 where
     C: LayoutOf<Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
@@ -2382,7 +2427,12 @@ where
         + HasParamEnv<'tcx>,
 {
     fn of_fn_ptr(cx: &C, sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
-        call::FnAbi::new_internal(cx, sig, extra_args, None, |ty, _| ArgAbi::new(cx.layout_of(ty)))
+        // Assume that fn pointers may always unwind
+        let codegen_fn_attr_flags = CodegenFnAttrFlags::UNWIND;
+
+        call::FnAbi::new_internal(cx, sig, extra_args, None, codegen_fn_attr_flags, |ty, _| {
+            ArgAbi::new(cx.layout_of(ty))
+        })
     }
 
     fn of_instance(cx: &C, instance: ty::Instance<'tcx>, extra_args: &[Ty<'tcx>]) -> Self {
@@ -2394,7 +2444,9 @@ where
             None
         };
 
-        call::FnAbi::new_internal(cx, sig, extra_args, caller_location, |ty, arg_idx| {
+        let attrs = cx.tcx().codegen_fn_attrs(instance.def_id()).flags;
+
+        call::FnAbi::new_internal(cx, sig, extra_args, caller_location, attrs, |ty, arg_idx| {
             let mut layout = cx.layout_of(ty);
             // Don't pass the vtable, it's not an argument of the virtual fn.
             // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait`
@@ -2450,6 +2502,7 @@ where
         sig: ty::PolyFnSig<'tcx>,
         extra_args: &[Ty<'tcx>],
         caller_location: Option<Ty<'tcx>>,
+        codegen_fn_attr_flags: CodegenFnAttrFlags,
         mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgAbi<'tcx, Ty<'tcx>>,
     ) -> Self {
         debug!("FnAbi::new_internal({:?}, {:?})", sig, extra_args);
@@ -2639,6 +2692,7 @@ where
             c_variadic: sig.c_variadic,
             fixed_count: inputs.len(),
             conv,
+            can_unwind: fn_can_unwind(cx.tcx().sess.panic_strategy(), codegen_fn_attr_flags, conv),
         };
         fn_abi.adjust_for_abi(cx, sig.abi);
         fn_abi
diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs
index 0ade0829ec3..7242bbcd2eb 100644
--- a/src/librustc_mir/borrow_check/borrow_set.rs
+++ b/src/librustc_mir/borrow_check/borrow_set.rs
@@ -206,7 +206,7 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> {
             let idx = self.idx_vec.push(borrow);
             self.location_map.insert(location, idx);
 
-            self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx);
+            self.insert_as_pending_if_two_phase(location, assigned_place, kind, idx);
 
             self.local_map.entry(borrowed_place.local).or_default().insert(idx);
         }
diff --git a/src/librustc_mir/borrow_check/constraint_generation.rs b/src/librustc_mir/borrow_check/constraint_generation.rs
index c7f395885a5..e0420d974fb 100644
--- a/src/librustc_mir/borrow_check/constraint_generation.rs
+++ b/src/librustc_mir/borrow_check/constraint_generation.rs
@@ -114,7 +114,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
     fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
         // When we see `X = ...`, then kill borrows of
         // `(*X).foo` and so forth.
-        self.record_killed_borrows_for_place(place, location);
+        self.record_killed_borrows_for_place(*place, location);
 
         self.super_assign(place, rvalue, location);
     }
@@ -139,7 +139,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
 
         // A `Call` terminator's return value can be a local which has borrows,
         // so we need to record those as `killed` as well.
-        if let TerminatorKind::Call { ref destination, .. } = terminator.kind {
+        if let TerminatorKind::Call { destination, .. } = terminator.kind {
             if let Some((place, _)) = destination {
                 self.record_killed_borrows_for_place(place, location);
             }
@@ -177,7 +177,7 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> {
 
     /// When recording facts for Polonius, records the borrows on the specified place
     /// as `killed`. For example, when assigning to a local, or on a call's return destination.
-    fn record_killed_borrows_for_place(&mut self, place: &Place<'tcx>, location: Location) {
+    fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) {
         if let Some(all_facts) = self.all_facts {
             let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
 
@@ -217,7 +217,7 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> {
                             let places_conflict = places_conflict::places_conflict(
                                 self.infcx.tcx,
                                 self.body,
-                                &self.borrow_set.borrows[borrow_index].borrowed_place,
+                                self.borrow_set.borrows[borrow_index].borrowed_place,
                                 place,
                                 places_conflict::PlaceConflictBias::NoOverlap,
                             );
diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
index a4bed18dcef..9df57605631 100644
--- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
@@ -247,7 +247,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_move_out_while_borrowed(
         &mut self,
         location: Location,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         borrow: &BorrowData<'tcx>,
     ) {
         debug!(
@@ -291,7 +291,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_use_while_mutably_borrowed(
         &mut self,
         location: Location,
-        (place, _span): (&Place<'tcx>, Span),
+        (place, _span): (Place<'tcx>, Span),
         borrow: &BorrowData<'tcx>,
     ) -> DiagnosticBuilder<'cx> {
         let borrow_spans = self.retrieve_borrow_spans(borrow);
@@ -330,7 +330,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_conflicting_borrow(
         &mut self,
         location: Location,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         gen_borrow_kind: BorrowKind,
         issued_borrow: &BorrowData<'tcx>,
     ) -> DiagnosticBuilder<'cx> {
@@ -347,7 +347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         };
 
         let (desc_place, msg_place, msg_borrow, union_type_name) =
-            self.describe_place_for_conflicting_borrow(place, &issued_borrow.borrowed_place);
+            self.describe_place_for_conflicting_borrow(place, issued_borrow.borrowed_place);
 
         let explanation = self.explain_why_borrow_contains_point(location, issued_borrow, None);
         let second_borrow_desc = if explanation.is_explained() { "second " } else { "" };
@@ -396,8 +396,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 );
                 self.suggest_split_at_mut_if_applicable(
                     &mut err,
-                    &place,
-                    &issued_borrow.borrowed_place,
+                    place,
+                    issued_borrow.borrowed_place,
                 );
                 err
             }
@@ -410,7 +410,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             (BorrowKind::Mut { .. }, BorrowKind::Shallow)
             | (BorrowKind::Unique, BorrowKind::Shallow) => {
                 if let Some(immutable_section_description) =
-                    self.classify_immutable_section(&issued_borrow.assigned_place)
+                    self.classify_immutable_section(issued_borrow.assigned_place)
                 {
                     let mut err = self.cannot_mutate_in_immutable_section(
                         span,
@@ -546,8 +546,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn suggest_split_at_mut_if_applicable(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        place: &Place<'tcx>,
-        borrowed_place: &Place<'tcx>,
+        place: Place<'tcx>,
+        borrowed_place: Place<'tcx>,
     ) {
         if let ([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) =
             (&place.projection[..], &borrowed_place.projection[..])
@@ -584,8 +584,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     /// >  mutable (via `a.u.s.b`) [E0502]
     pub(in crate::borrow_check) fn describe_place_for_conflicting_borrow(
         &self,
-        first_borrowed_place: &Place<'tcx>,
-        second_borrowed_place: &Place<'tcx>,
+        first_borrowed_place: Place<'tcx>,
+        second_borrowed_place: Place<'tcx>,
     ) -> (String, String, String, String) {
         // Define a small closure that we can use to check if the type of a place
         // is a union.
@@ -615,13 +615,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     cursor = proj_base;
 
                     match elem {
-                        ProjectionElem::Field(field, _)
-                            if union_ty(*local, proj_base).is_some() =>
-                        {
-                            return Some((
-                                PlaceRef { local: *local, projection: proj_base },
-                                field,
-                            ));
+                        ProjectionElem::Field(field, _) if union_ty(local, proj_base).is_some() => {
+                            return Some((PlaceRef { local, projection: proj_base }, field));
                         }
                         _ => {}
                     }
@@ -631,7 +626,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             .and_then(|(target_base, target_field)| {
                 // With the place of a union and a field access into it, we traverse the second
                 // borrowed place and look for a access to a different field of the same union.
-                let Place { local, ref projection } = *second_borrowed_place;
+                let Place { local, ref projection } = second_borrowed_place;
 
                 let mut cursor = &projection[..];
                 while let [proj_base @ .., elem] = cursor {
@@ -682,7 +677,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &mut self,
         location: Location,
         borrow: &BorrowData<'tcx>,
-        place_span: (&Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         kind: Option<WriteKind>,
     ) {
         debug!(
@@ -967,7 +962,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &mut self,
         location: Location,
         borrow: &BorrowData<'tcx>,
-        (place, drop_span): (&Place<'tcx>, Span),
+        (place, drop_span): (Place<'tcx>, Span),
         kind: Option<WriteKind>,
         dropped_ty: Ty<'tcx>,
     ) {
@@ -1379,7 +1374,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_illegal_mutation_of_borrowed(
         &mut self,
         location: Location,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         loan: &BorrowData<'tcx>,
     ) {
         let loan_spans = self.retrieve_borrow_spans(loan);
@@ -1387,7 +1382,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         let descr_place = self.describe_any_place(place.as_ref());
         if loan.kind == BorrowKind::Shallow {
-            if let Some(section) = self.classify_immutable_section(&loan.assigned_place) {
+            if let Some(section) = self.classify_immutable_section(loan.assigned_place) {
                 let mut err = self.cannot_mutate_in_immutable_section(
                     span,
                     loan_span,
@@ -1432,9 +1427,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub(in crate::borrow_check) fn report_illegal_reassignment(
         &mut self,
         _location: Location,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         assigned_span: Span,
-        err_place: &Place<'tcx>,
+        err_place: Place<'tcx>,
     ) {
         let (from_arg, local_decl, local_name) = match err_place.as_local() {
             Some(local) => (
@@ -1539,17 +1534,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     }
 
     /// Describe the reason for the fake borrow that was assigned to `place`.
-    fn classify_immutable_section(&self, place: &Place<'tcx>) -> Option<&'static str> {
+    fn classify_immutable_section(&self, place: Place<'tcx>) -> Option<&'static str> {
         use rustc_middle::mir::visit::Visitor;
-        struct FakeReadCauseFinder<'a, 'tcx> {
-            place: &'a Place<'tcx>,
+        struct FakeReadCauseFinder<'tcx> {
+            place: Place<'tcx>,
             cause: Option<FakeReadCause>,
         }
-        impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'_, 'tcx> {
+        impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'tcx> {
             fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
                 match statement {
-                    Statement { kind: StatementKind::FakeRead(cause, box ref place), .. }
-                        if *place == *self.place =>
+                    Statement { kind: StatementKind::FakeRead(cause, box place), .. }
+                        if *place == self.place =>
                     {
                         self.cause = Some(*cause);
                     }
diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
index a3ab36b8443..7340e88f19b 100644
--- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
@@ -286,7 +286,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &self,
         location: Location,
         borrow: &BorrowData<'tcx>,
-        kind_place: Option<(WriteKind, &Place<'tcx>)>,
+        kind_place: Option<(WriteKind, Place<'tcx>)>,
     ) -> BorrowExplanation {
         debug!(
             "explain_why_borrow_contains_point(location={:?}, borrow={:?}, kind_place={:?})",
diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
index 3c198dc74ce..d32533b6ce9 100644
--- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
@@ -105,7 +105,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         // whether or not the right-hand side is a place expression
                         if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
                             VarBindingForm {
-                                opt_match_place: Some((ref opt_match_place, match_span)),
+                                opt_match_place: Some((opt_match_place, match_span)),
                                 binding_mode: _,
                                 opt_ty_info: _,
                                 pat_span: _,
@@ -117,7 +117,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                                 grouped_errors,
                                 kind,
                                 original_path,
-                                move_from,
+                                *move_from,
                                 local,
                                 opt_match_place,
                                 match_span,
@@ -143,16 +143,16 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         grouped_errors: &mut Vec<GroupedMoveError<'tcx>>,
         kind: IllegalMoveOriginKind<'tcx>,
         original_path: Place<'tcx>,
-        move_from: &Place<'tcx>,
+        move_from: Place<'tcx>,
         bind_to: Local,
-        match_place: &Option<Place<'tcx>>,
+        match_place: Option<Place<'tcx>>,
         match_span: Span,
         statement_span: Span,
     ) {
         debug!("append_binding_error(match_place={:?}, match_span={:?})", match_place, match_span);
 
         let from_simple_let = match_place.is_none();
-        let match_place = match_place.as_ref().unwrap_or(move_from);
+        let match_place = match_place.unwrap_or(move_from);
 
         match self.move_data.rev_lookup.find(match_place.as_ref()) {
             // Error with the match place
@@ -178,7 +178,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 };
                 grouped_errors.push(GroupedMoveError::MovesFromPlace {
                     span,
-                    move_from: *match_place,
+                    move_from,
                     original_path,
                     kind,
                     binds_to,
@@ -223,14 +223,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             let (span, use_spans, original_path, kind): (
                 Span,
                 Option<UseSpans>,
-                &Place<'tcx>,
+                Place<'tcx>,
                 &IllegalMoveOriginKind<'_>,
             ) = match error {
-                GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. }
-                | GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => {
+                GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
+                | GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
                     (span, None, original_path, kind)
                 }
-                GroupedMoveError::OtherIllegalMove { use_spans, ref original_path, ref kind } => {
+                GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
                     (use_spans.args_or_use(), Some(use_spans), original_path, kind)
                 }
             };
@@ -247,7 +247,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     IllegalMoveOriginKind::BorrowedContent { target_place } => self
                         .report_cannot_move_from_borrowed_content(
                             original_path,
-                            target_place,
+                            *target_place,
                             span,
                             use_spans,
                         ),
@@ -268,7 +268,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
     fn report_cannot_move_from_static(
         &mut self,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         span: Span,
     ) -> DiagnosticBuilder<'a> {
         let description = if place.projection.len() == 1 {
@@ -288,8 +288,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
     fn report_cannot_move_from_borrowed_content(
         &mut self,
-        move_place: &Place<'tcx>,
-        deref_target_place: &Place<'tcx>,
+        move_place: Place<'tcx>,
+        deref_target_place: Place<'tcx>,
         span: Span,
         use_spans: Option<UseSpans>,
     ) -> DiagnosticBuilder<'a> {
diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
index 2fe72e1aa08..35edd3d803d 100644
--- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
@@ -22,7 +22,7 @@ pub(crate) enum AccessKind {
 impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
     pub(crate) fn report_mutability_error(
         &mut self,
-        access_place: &Place<'tcx>,
+        access_place: Place<'tcx>,
         span: Span,
         the_place_err: PlaceRef<'tcx>,
         error_access: AccessKind,
diff --git a/src/librustc_mir/borrow_check/invalidation.rs b/src/librustc_mir/borrow_check/invalidation.rs
index 1639b7262b0..318751113b2 100644
--- a/src/librustc_mir/borrow_check/invalidation.rs
+++ b/src/librustc_mir/borrow_check/invalidation.rs
@@ -56,33 +56,33 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
     fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
         self.check_activations(location);
 
-        match statement.kind {
-            StatementKind::Assign(box (ref lhs, ref rhs)) => {
+        match &statement.kind {
+            StatementKind::Assign(box (lhs, rhs)) => {
                 self.consume_rvalue(location, rhs);
 
-                self.mutate_place(location, lhs, Shallow(None), JustWrite);
+                self.mutate_place(location, *lhs, Shallow(None), JustWrite);
             }
             StatementKind::FakeRead(_, _) => {
                 // Only relevant for initialized/liveness/safety checks.
             }
-            StatementKind::SetDiscriminant { ref place, variant_index: _ } => {
-                self.mutate_place(location, place, Shallow(None), JustWrite);
+            StatementKind::SetDiscriminant { place, variant_index: _ } => {
+                self.mutate_place(location, **place, Shallow(None), JustWrite);
             }
-            StatementKind::LlvmInlineAsm(ref asm) => {
+            StatementKind::LlvmInlineAsm(asm) => {
                 for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) {
                     if o.is_indirect {
                         // FIXME(eddyb) indirect inline asm outputs should
                         // be encoded through MIR place derefs instead.
                         self.access_place(
                             location,
-                            output,
+                            *output,
                             (Deep, Read(ReadKind::Copy)),
                             LocalMutationIsAllowed::No,
                         );
                     } else {
                         self.mutate_place(
                             location,
-                            output,
+                            *output,
                             if o.is_rw { Deep } else { Shallow(None) },
                             if o.is_rw { WriteAndRead } else { JustWrite },
                         );
@@ -102,7 +102,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
             StatementKind::StorageDead(local) => {
                 self.access_place(
                     location,
-                    &Place::from(local),
+                    Place::from(*local),
                     (Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
                     LocalMutationIsAllowed::Yes,
                 );
@@ -119,27 +119,27 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
             TerminatorKind::SwitchInt { ref discr, switch_ty: _, values: _, targets: _ } => {
                 self.consume_operand(location, discr);
             }
-            TerminatorKind::Drop { location: ref drop_place, target: _, unwind: _ } => {
+            TerminatorKind::Drop { location: drop_place, target: _, unwind: _ } => {
                 self.access_place(
                     location,
-                    drop_place,
+                    *drop_place,
                     (AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
                     LocalMutationIsAllowed::Yes,
                 );
             }
             TerminatorKind::DropAndReplace {
-                location: ref drop_place,
+                location: drop_place,
                 value: ref new_value,
                 target: _,
                 unwind: _,
             } => {
-                self.mutate_place(location, drop_place, Deep, JustWrite);
+                self.mutate_place(location, *drop_place, Deep, JustWrite);
                 self.consume_operand(location, new_value);
             }
             TerminatorKind::Call {
                 ref func,
                 ref args,
-                ref destination,
+                destination,
                 cleanup: _,
                 from_hir_call: _,
             } => {
@@ -147,8 +147,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
                 for arg in args {
                     self.consume_operand(location, arg);
                 }
-                if let Some((ref dest, _ /*bb*/)) = *destination {
-                    self.mutate_place(location, dest, Deep, JustWrite);
+                if let Some((dest, _ /*bb*/)) = destination {
+                    self.mutate_place(location, *dest, Deep, JustWrite);
                 }
             }
             TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => {
@@ -166,19 +166,19 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
                 let borrow_set = self.borrow_set.clone();
                 let resume = self.location_table.start_index(resume.start_location());
                 for i in borrow_set.borrows.indices() {
-                    if borrow_of_local_data(&borrow_set.borrows[i].borrowed_place) {
+                    if borrow_of_local_data(borrow_set.borrows[i].borrowed_place) {
                         self.all_facts.invalidates.push((resume, i));
                     }
                 }
 
-                self.mutate_place(location, resume_arg, Deep, JustWrite);
+                self.mutate_place(location, *resume_arg, Deep, JustWrite);
             }
             TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
                 // Invalidate all borrows of local places
                 let borrow_set = self.borrow_set.clone();
                 let start = self.location_table.start_index(location);
                 for i in borrow_set.borrows.indices() {
-                    if borrow_of_local_data(&borrow_set.borrows[i].borrowed_place) {
+                    if borrow_of_local_data(borrow_set.borrows[i].borrowed_place) {
                         self.all_facts.invalidates.push((start, i));
                     }
                 }
@@ -201,7 +201,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     fn mutate_place(
         &mut self,
         location: Location,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         kind: AccessDepth,
         _mode: MutateMode,
     ) {
@@ -216,7 +216,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     /// Simulates consumption of an operand.
     fn consume_operand(&mut self, location: Location, operand: &Operand<'tcx>) {
         match *operand {
-            Operand::Copy(ref place) => {
+            Operand::Copy(place) => {
                 self.access_place(
                     location,
                     place,
@@ -224,7 +224,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
                     LocalMutationIsAllowed::No,
                 );
             }
-            Operand::Move(ref place) => {
+            Operand::Move(place) => {
                 self.access_place(
                     location,
                     place,
@@ -239,7 +239,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     // Simulates consumption of an rvalue
     fn consume_rvalue(&mut self, location: Location, rvalue: &Rvalue<'tcx>) {
         match *rvalue {
-            Rvalue::Ref(_ /*rgn*/, bk, ref place) => {
+            Rvalue::Ref(_ /*rgn*/, bk, place) => {
                 let access_kind = match bk {
                     BorrowKind::Shallow => {
                         (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
@@ -258,7 +258,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
                 self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
             }
 
-            Rvalue::AddressOf(mutability, ref place) => {
+            Rvalue::AddressOf(mutability, place) => {
                 let access_kind = match mutability {
                     Mutability::Mut => (
                         Deep,
@@ -279,7 +279,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
                 self.consume_operand(location, operand)
             }
 
-            Rvalue::Len(ref place) | Rvalue::Discriminant(ref place) => {
+            Rvalue::Len(place) | Rvalue::Discriminant(place) => {
                 let af = match *rvalue {
                     Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
                     Rvalue::Discriminant(..) => None,
@@ -313,7 +313,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     fn access_place(
         &mut self,
         location: Location,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         kind: (AccessDepth, ReadOrWrite),
         _is_local_mutation_allowed: LocalMutationIsAllowed,
     ) {
@@ -325,7 +325,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
     fn check_access_for_conflict(
         &mut self,
         location: Location,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         sd: AccessDepth,
         rw: ReadOrWrite,
     ) {
@@ -413,7 +413,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
 
             self.access_place(
                 location,
-                &borrow.borrowed_place,
+                borrow.borrowed_place,
                 (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)),
                 LocalMutationIsAllowed::No,
             );
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 0aeabdb4dca..52847af214f 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -308,8 +308,7 @@ fn do_mir_borrowck<'a, 'tcx>(
     // Convert any reservation warnings into lints.
     let reservation_warnings = mem::take(&mut mbcx.reservation_warnings);
     for (_, (place, span, location, bk, borrow)) in reservation_warnings {
-        let mut initial_diag =
-            mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow);
+        let mut initial_diag = mbcx.report_conflicting_borrow(location, (place, span), bk, &borrow);
 
         let scope = mbcx.body.source_info(location).scope;
         let lint_root = match &mbcx.body.source_scopes[scope].local_data {
@@ -523,11 +522,11 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
 
         self.check_activations(location, span, flow_state);
 
-        match stmt.kind {
-            StatementKind::Assign(box (ref lhs, ref rhs)) => {
+        match &stmt.kind {
+            StatementKind::Assign(box (lhs, ref rhs)) => {
                 self.consume_rvalue(location, (rhs, span), flow_state);
 
-                self.mutate_place(location, (lhs, span), Shallow(None), JustWrite, flow_state);
+                self.mutate_place(location, (*lhs, span), Shallow(None), JustWrite, flow_state);
             }
             StatementKind::FakeRead(_, box ref place) => {
                 // Read for match doesn't access any memory and is used to
@@ -547,8 +546,8 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
                     flow_state,
                 );
             }
-            StatementKind::SetDiscriminant { ref place, variant_index: _ } => {
-                self.mutate_place(location, (place, span), Shallow(None), JustWrite, flow_state);
+            StatementKind::SetDiscriminant { place, variant_index: _ } => {
+                self.mutate_place(location, (**place, span), Shallow(None), JustWrite, flow_state);
             }
             StatementKind::LlvmInlineAsm(ref asm) => {
                 for (o, output) in asm.asm.outputs.iter().zip(asm.outputs.iter()) {
@@ -557,7 +556,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
                         // be encoded through MIR place derefs instead.
                         self.access_place(
                             location,
-                            (output, o.span),
+                            (*output, o.span),
                             (Deep, Read(ReadKind::Copy)),
                             LocalMutationIsAllowed::No,
                             flow_state,
@@ -571,7 +570,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
                     } else {
                         self.mutate_place(
                             location,
-                            (output, o.span),
+                            (*output, o.span),
                             if o.is_rw { Deep } else { Shallow(None) },
                             if o.is_rw { WriteAndRead } else { JustWrite },
                             flow_state,
@@ -592,7 +591,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
             StatementKind::StorageDead(local) => {
                 self.access_place(
                     location,
-                    (&Place::from(local), span),
+                    (Place::from(*local), span),
                     (Shallow(None), Write(WriteKind::StorageDeadOrDrop)),
                     LocalMutationIsAllowed::Yes,
                     flow_state,
@@ -638,14 +637,14 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
 
                 self.access_place(
                     loc,
-                    (drop_place, span),
+                    (*drop_place, span),
                     (AccessDepth::Drop, Write(WriteKind::StorageDeadOrDrop)),
                     LocalMutationIsAllowed::Yes,
                     flow_state,
                 );
             }
             TerminatorKind::DropAndReplace {
-                location: ref drop_place,
+                location: drop_place,
                 value: ref new_value,
                 target: _,
                 unwind: _,
@@ -664,7 +663,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
                 for arg in args {
                     self.consume_operand(loc, (arg, span), flow_state);
                 }
-                if let Some((ref dest, _ /*bb*/)) = *destination {
+                if let Some((dest, _ /*bb*/)) = *destination {
                     self.mutate_place(loc, (dest, span), Deep, JustWrite, flow_state);
                 }
             }
@@ -677,7 +676,7 @@ impl<'cx, 'tcx> dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tc
                 }
             }
 
-            TerminatorKind::Yield { ref value, resume: _, ref resume_arg, drop: _ } => {
+            TerminatorKind::Yield { ref value, resume: _, resume_arg, drop: _ } => {
                 self.consume_operand(loc, (value, span), flow_state);
                 self.mutate_place(loc, (resume_arg, span), Deep, JustWrite, flow_state);
             }
@@ -884,7 +883,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn access_place(
         &mut self,
         location: Location,
-        place_span: (&Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         kind: (AccessDepth, ReadOrWrite),
         is_local_mutation_allowed: LocalMutationIsAllowed,
         flow_state: &Flows<'cx, 'tcx>,
@@ -905,7 +904,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         // Check is_empty() first because it's the common case, and doing that
         // way we avoid the clone() call.
         if !self.access_place_error_reported.is_empty()
-            && self.access_place_error_reported.contains(&(*place_span.0, place_span.1))
+            && self.access_place_error_reported.contains(&(place_span.0, place_span.1))
         {
             debug!(
                 "access_place: suppressing error place_span=`{:?}` kind=`{:?}`",
@@ -933,14 +932,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         if conflict_error || mutability_error {
             debug!("access_place: logging error place_span=`{:?}` kind=`{:?}`", place_span, kind);
 
-            self.access_place_error_reported.insert((*place_span.0, place_span.1));
+            self.access_place_error_reported.insert((place_span.0, place_span.1));
         }
     }
 
     fn check_access_for_conflict(
         &mut self,
         location: Location,
-        place_span: (&Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         sd: AccessDepth,
         rw: ReadOrWrite,
         flow_state: &Flows<'cx, 'tcx>,
@@ -1043,7 +1042,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     // these sepately so that we only emit a warning if borrow
                     // checking was otherwise successful.
                     this.reservation_warnings
-                        .insert(bi, (*place_span.0, place_span.1, location, bk, borrow.clone()));
+                        .insert(bi, (place_span.0, place_span.1, location, bk, borrow.clone()));
 
                     // Don't suppress actual errors.
                     Control::Continue
@@ -1100,7 +1099,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn mutate_place(
         &mut self,
         location: Location,
-        place_span: (&'cx Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         kind: AccessDepth,
         mode: MutateMode,
         flow_state: &Flows<'cx, 'tcx>,
@@ -1150,7 +1149,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         flow_state: &Flows<'cx, 'tcx>,
     ) {
         match *rvalue {
-            Rvalue::Ref(_ /*rgn*/, bk, ref place) => {
+            Rvalue::Ref(_ /*rgn*/, bk, place) => {
                 let access_kind = match bk {
                     BorrowKind::Shallow => {
                         (Shallow(Some(ArtificialField::ShallowBorrow)), Read(ReadKind::Borrow(bk)))
@@ -1188,7 +1187,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 );
             }
 
-            Rvalue::AddressOf(mutability, ref place) => {
+            Rvalue::AddressOf(mutability, place) => {
                 let access_kind = match mutability {
                     Mutability::Mut => (
                         Deep,
@@ -1222,7 +1221,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 self.consume_operand(location, (operand, span), flow_state)
             }
 
-            Rvalue::Len(ref place) | Rvalue::Discriminant(ref place) => {
+            Rvalue::Len(place) | Rvalue::Discriminant(place) => {
                 let af = match *rvalue {
                     Rvalue::Len(..) => Some(ArtificialField::ArrayLength),
                     Rvalue::Discriminant(..) => None,
@@ -1283,7 +1282,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     }
 
     fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) {
-        let propagate_closure_used_mut_place = |this: &mut Self, place: &Place<'tcx>| {
+        let propagate_closure_used_mut_place = |this: &mut Self, place: Place<'tcx>| {
             if !place.projection.is_empty() {
                 if let Some(field) = this.is_upvar_field_projection(place.as_ref()) {
                     this.used_mut_upvars.push(field);
@@ -1297,7 +1296,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         // captures of a closure are copied/moved directly
         // when generating MIR.
         match *operand {
-            Operand::Move(ref place) | Operand::Copy(ref place) => {
+            Operand::Move(place) | Operand::Copy(place) => {
                 match place.as_local() {
                     Some(local) if !self.body.local_decls[local].is_user_variable() => {
                         if self.body.local_decls[local].ty.is_mutable_ptr() {
@@ -1336,8 +1335,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         let stmt = &bbd.statements[loc.statement_index];
                         debug!("temporary assigned in: stmt={:?}", stmt);
 
-                        if let StatementKind::Assign(box (_, Rvalue::Ref(_, _, ref source))) =
-                            stmt.kind
+                        if let StatementKind::Assign(box (_, Rvalue::Ref(_, _, source))) = stmt.kind
                         {
                             propagate_closure_used_mut_place(self, source);
                         } else {
@@ -1361,7 +1359,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         flow_state: &Flows<'cx, 'tcx>,
     ) {
         match *operand {
-            Operand::Copy(ref place) => {
+            Operand::Copy(place) => {
                 // copy of place: check if this is "copy of frozen path"
                 // (FIXME: see check_loans.rs)
                 self.access_place(
@@ -1380,7 +1378,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     flow_state,
                 );
             }
-            Operand::Move(ref place) => {
+            Operand::Move(place) => {
                 // move of place: check if this is move of already borrowed path
                 self.access_place(
                     location,
@@ -1411,7 +1409,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         span: Span,
     ) {
         debug!("check_for_invalidation_at_exit({:?})", borrow);
-        let place = &borrow.borrowed_place;
+        let place = borrow.borrowed_place;
         let mut root_place = PlaceRef { local: place.local, projection: &[] };
 
         // FIXME(nll-rfc#40): do more precise destructor tracking here. For now
@@ -1465,7 +1463,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span) {
         debug!("check_for_local_borrow({:?})", borrow);
 
-        if borrow_of_local_data(&borrow.borrowed_place) {
+        if borrow_of_local_data(borrow.borrowed_place) {
             let err = self.cannot_borrow_across_generator_yield(
                 self.retrieve_borrow_spans(borrow).var_or_use(),
                 yield_span,
@@ -1491,7 +1489,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
             self.access_place(
                 location,
-                (&borrow.borrowed_place, span),
+                (borrow.borrowed_place, span),
                 (Deep, Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index)),
                 LocalMutationIsAllowed::No,
                 flow_state,
@@ -1506,7 +1504,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         &mut self,
         location: Location,
         local: Local,
-        place_span: (&Place<'tcx>, Span),
+        place_span: (Place<'tcx>, Span),
         flow_state: &Flows<'cx, 'tcx>,
     ) {
         debug!("check_if_reassignment_to_immutable_state({:?})", local);
@@ -1730,7 +1728,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn check_if_assigned_path_is_moved(
         &mut self,
         location: Location,
-        (place, span): (&'cx Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         flow_state: &Flows<'cx, 'tcx>,
     ) {
         debug!("check_if_assigned_path_is_moved place: {:?}", place);
@@ -1903,7 +1901,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     /// Returns `true` if an error is reported.
     fn check_access_permissions(
         &mut self,
-        (place, span): (&Place<'tcx>, Span),
+        (place, span): (Place<'tcx>, Span),
         kind: ReadOrWrite,
         is_local_mutation_allowed: LocalMutationIsAllowed,
         flow_state: &Flows<'cx, 'tcx>,
diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs
index 83e017c3137..678ab3ed323 100644
--- a/src/librustc_mir/borrow_check/nll.rs
+++ b/src/librustc_mir/borrow_check/nll.rs
@@ -317,7 +317,7 @@ pub(super) fn dump_mir_results<'a, 'tcx>(
     regioncx: &RegionInferenceContext<'_>,
     closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
 ) {
-    if !mir_util::dump_enabled(infcx.tcx, "nll", source) {
+    if !mir_util::dump_enabled(infcx.tcx, "nll", source.def_id()) {
         return;
     }
 
diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs
index aa5065300ea..f5238e7b7be 100644
--- a/src/librustc_mir/borrow_check/path_utils.rs
+++ b/src/librustc_mir/borrow_check/path_utils.rs
@@ -27,7 +27,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
     _location: Location,
-    access_place: (AccessDepth, &Place<'tcx>),
+    access_place: (AccessDepth, Place<'tcx>),
     borrow_set: &BorrowSet<'tcx>,
     candidates: I,
     mut op: F,
@@ -48,7 +48,7 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
         if places_conflict::borrow_conflicts_with_place(
             tcx,
             body,
-            &borrowed.borrowed_place,
+            borrowed.borrowed_place,
             borrowed.kind,
             place.as_ref(),
             access,
@@ -130,7 +130,7 @@ pub(super) fn is_active<'tcx>(
 
 /// Determines if a given borrow is borrowing local data
 /// This is called for all Yield expressions on movable generators
-pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
+pub(super) fn borrow_of_local_data(place: Place<'_>) -> bool {
     // Reborrow of already borrowed data is ignored
     // Any errors will be caught on the initial borrow
     !place.is_indirect()
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index 876c9728d00..d48df6a9109 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -24,8 +24,8 @@ crate enum PlaceConflictBias {
 crate fn places_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    borrow_place: &Place<'tcx>,
-    access_place: &Place<'tcx>,
+    borrow_place: Place<'tcx>,
+    access_place: Place<'tcx>,
     bias: PlaceConflictBias,
 ) -> bool {
     borrow_conflicts_with_place(
@@ -46,7 +46,7 @@ crate fn places_conflict<'tcx>(
 pub(super) fn borrow_conflicts_with_place<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    borrow_place: &Place<'tcx>,
+    borrow_place: Place<'tcx>,
     borrow_kind: BorrowKind,
     access_place: PlaceRef<'tcx>,
     access: AccessDepth,
@@ -71,7 +71,7 @@ pub(super) fn borrow_conflicts_with_place<'tcx>(
 fn place_components_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    borrow_place: &Place<'tcx>,
+    borrow_place: Place<'tcx>,
     borrow_kind: BorrowKind,
     access_place: PlaceRef<'tcx>,
     access: AccessDepth,
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs
index eb1527b874e..2da72f3bcc5 100644
--- a/src/librustc_mir/borrow_check/used_muts.rs
+++ b/src/librustc_mir/borrow_check/used_muts.rs
@@ -51,7 +51,7 @@ struct GatherUsedMutsVisitor<'visit, 'cx, 'tcx> {
 }
 
 impl GatherUsedMutsVisitor<'_, '_, '_> {
-    fn remove_never_initialized_mut_locals(&mut self, into: &Place<'_>) {
+    fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) {
         // Remove any locals that we found were initialized from the
         // `never_initialized_mut_locals` set. At the end, the only remaining locals will
         // be those that were never initialized - we will consider those as being used as
@@ -66,10 +66,10 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
         debug!("visit_terminator_kind: kind={:?}", kind);
         match &kind {
             TerminatorKind::Call { destination: Some((into, _)), .. } => {
-                self.remove_never_initialized_mut_locals(&into);
+                self.remove_never_initialized_mut_locals(*into);
             }
             TerminatorKind::DropAndReplace { location, .. } => {
-                self.remove_never_initialized_mut_locals(&location);
+                self.remove_never_initialized_mut_locals(*location);
             }
             _ => {}
         }
@@ -82,7 +82,7 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
                     never_initialized_mut_locals={:?}",
                 statement, into.local, self.never_initialized_mut_locals
             );
-            self.remove_never_initialized_mut_locals(into);
+            self.remove_never_initialized_mut_locals(*into);
         }
     }
 
diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs
index f9511921a87..91b342ae5c3 100644
--- a/src/librustc_mir/dataflow/drop_flag_effects.rs
+++ b/src/librustc_mir/dataflow/drop_flag_effects.rs
@@ -49,7 +49,7 @@ where
 fn place_contents_drop_state_cannot_differ<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    place: &mir::Place<'tcx>,
+    place: mir::Place<'tcx>,
 ) -> bool {
     let ty = place.ty(body, tcx).ty;
     match ty.kind {
@@ -110,7 +110,7 @@ pub(crate) fn on_all_children_bits<'tcx, F>(
         move_data: &MoveData<'tcx>,
         path: MovePathIndex,
     ) -> bool {
-        place_contents_drop_state_cannot_differ(tcx, body, &move_data.move_paths[path].place)
+        place_contents_drop_state_cannot_differ(tcx, body, move_data.move_paths[path].place)
     }
 
     fn on_all_children_bits<'tcx, F>(
diff --git a/src/librustc_mir/dataflow/framework/cursor.rs b/src/librustc_mir/dataflow/framework/cursor.rs
index ed7c75f2f9d..39676d03740 100644
--- a/src/librustc_mir/dataflow/framework/cursor.rs
+++ b/src/librustc_mir/dataflow/framework/cursor.rs
@@ -135,14 +135,14 @@ where
                     target.block,
                     func,
                     args,
-                    return_place,
+                    *return_place,
                 );
             }
             TerminatorKind::Yield { resume, resume_arg, .. } => {
                 self.results.borrow().analysis.apply_yield_resume_effect(
                     &mut self.state,
                     *resume,
-                    resume_arg,
+                    *resume_arg,
                 );
             }
             _ => {}
diff --git a/src/librustc_mir/dataflow/framework/engine.rs b/src/librustc_mir/dataflow/framework/engine.rs
index fc2a1bc62a6..2a9d2d99c8a 100644
--- a/src/librustc_mir/dataflow/framework/engine.rs
+++ b/src/librustc_mir/dataflow/framework/engine.rs
@@ -15,6 +15,7 @@ use rustc_span::symbol::{sym, Symbol};
 
 use super::graphviz;
 use super::{Analysis, GenKillAnalysis, GenKillSet, Results};
+use crate::util::pretty::dump_enabled;
 
 /// A solver for dataflow problems.
 pub struct Engine<'a, 'tcx, A>
@@ -228,7 +229,7 @@ where
                     self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list);
                 }
 
-                self.analysis.apply_yield_resume_effect(in_out, target, &resume_arg);
+                self.analysis.apply_yield_resume_effect(in_out, target, resume_arg);
                 self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
             }
 
@@ -272,7 +273,7 @@ where
                     }
                 }
 
-                if let Some((ref dest_place, dest_bb)) = *destination {
+                if let Some((dest_place, dest_bb)) = *destination {
                     // N.B.: This must be done *last*, otherwise the unwind path will see the call
                     // return effect.
                     self.analysis.apply_call_return_effect(in_out, bb, func, args, dest_place);
@@ -314,7 +315,7 @@ where
         in_out: &mut BitSet<A::Idx>,
         bb: BasicBlock,
         enum_def: &'tcx ty::AdtDef,
-        enum_place: &mir::Place<'tcx>,
+        enum_place: mir::Place<'tcx>,
         dirty_list: &mut WorkQueue<BasicBlock>,
         values: &[u128],
         targets: &[BasicBlock],
@@ -361,14 +362,14 @@ fn switch_on_enum_discriminant(
     tcx: TyCtxt<'tcx>,
     body: &'mir mir::Body<'tcx>,
     block: &'mir mir::BasicBlockData<'tcx>,
-    switch_on: &mir::Place<'tcx>,
-) -> Option<(&'mir mir::Place<'tcx>, &'tcx ty::AdtDef)> {
+    switch_on: mir::Place<'tcx>,
+) -> Option<(mir::Place<'tcx>, &'tcx ty::AdtDef)> {
     match block.statements.last().map(|stmt| &stmt.kind) {
         Some(mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated))))
-            if lhs == switch_on =>
+            if *lhs == switch_on =>
         {
             match &discriminated.ty(body, tcx).ty.kind {
-                ty::Adt(def, _) => Some((discriminated, def)),
+                ty::Adt(def, _) => Some((*discriminated, def)),
 
                 // `Rvalue::Discriminant` is also used to get the active yield point for a
                 // generator, but we do not need edge-specific effects in that case. This may
@@ -400,12 +401,25 @@ where
     let attrs = match RustcMirAttrs::parse(tcx, def_id) {
         Ok(attrs) => attrs,
 
-        // Invalid `rustc_mir` attrs will be reported using `span_err`.
+        // Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse`
         Err(()) => return Ok(()),
     };
 
     let path = match attrs.output_path(A::NAME) {
         Some(path) => path,
+
+        None if tcx.sess.opts.debugging_opts.dump_mir_dataflow
+            && dump_enabled(tcx, A::NAME, def_id) =>
+        {
+            let mut path = PathBuf::from(&tcx.sess.opts.debugging_opts.dump_mir_dir);
+
+            let item_name = ty::print::with_forced_impl_filename_line(|| {
+                tcx.def_path(def_id).to_filename_friendly_no_crate()
+            });
+            path.push(format!("rustc.{}.{}.dot", item_name, A::NAME));
+            path
+        }
+
         None => return Ok(()),
     };
 
@@ -430,7 +444,12 @@ where
 
     let graphviz = graphviz::Formatter::new(body, def_id, results, &mut *formatter);
     dot::render_opts(&graphviz, &mut buf, &[dot::RenderOption::Monospace])?;
+
+    if let Some(parent) = path.parent() {
+        fs::create_dir_all(parent)?;
+    }
     fs::write(&path, buf)?;
+
     Ok(())
 }
 
diff --git a/src/librustc_mir/dataflow/framework/mod.rs b/src/librustc_mir/dataflow/framework/mod.rs
index 91c4b5ad634..fd2a3d5ea28 100644
--- a/src/librustc_mir/dataflow/framework/mod.rs
+++ b/src/librustc_mir/dataflow/framework/mod.rs
@@ -225,7 +225,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
         block: BasicBlock,
         func: &mir::Operand<'tcx>,
         args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     );
 
     /// Updates the current dataflow state with the effect of resuming from a `Yield` terminator.
@@ -238,7 +238,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
         &self,
         _state: &mut BitSet<Self::Idx>,
         _resume_block: BasicBlock,
-        _resume_place: &mir::Place<'tcx>,
+        _resume_place: mir::Place<'tcx>,
     ) {
     }
 
@@ -251,7 +251,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
         &self,
         _state: &mut BitSet<Self::Idx>,
         _block: BasicBlock,
-        _enum_place: &mir::Place<'tcx>,
+        _enum_place: mir::Place<'tcx>,
         _adt: &ty::AdtDef,
         _variant: VariantIdx,
     ) {
@@ -332,7 +332,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
         block: BasicBlock,
         func: &mir::Operand<'tcx>,
         args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     );
 
     /// See `Analysis::apply_yield_resume_effect`.
@@ -340,7 +340,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
         &self,
         _trans: &mut BitSet<Self::Idx>,
         _resume_block: BasicBlock,
-        _resume_place: &mir::Place<'tcx>,
+        _resume_place: mir::Place<'tcx>,
     ) {
     }
 
@@ -349,7 +349,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
         &self,
         _state: &mut impl GenKill<Self::Idx>,
         _block: BasicBlock,
-        _enum_place: &mir::Place<'tcx>,
+        _enum_place: mir::Place<'tcx>,
         _adt: &ty::AdtDef,
         _variant: VariantIdx,
     ) {
@@ -402,7 +402,7 @@ where
         block: BasicBlock,
         func: &mir::Operand<'tcx>,
         args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     ) {
         self.call_return_effect(state, block, func, args, return_place);
     }
@@ -411,7 +411,7 @@ where
         &self,
         state: &mut BitSet<Self::Idx>,
         resume_block: BasicBlock,
-        resume_place: &mir::Place<'tcx>,
+        resume_place: mir::Place<'tcx>,
     ) {
         self.yield_resume_effect(state, resume_block, resume_place);
     }
@@ -420,7 +420,7 @@ where
         &self,
         state: &mut BitSet<Self::Idx>,
         block: BasicBlock,
-        enum_place: &mir::Place<'tcx>,
+        enum_place: mir::Place<'tcx>,
         adt: &ty::AdtDef,
         variant: VariantIdx,
     ) {
diff --git a/src/librustc_mir/dataflow/framework/tests.rs b/src/librustc_mir/dataflow/framework/tests.rs
index c38cb456667..8c65b7452d1 100644
--- a/src/librustc_mir/dataflow/framework/tests.rs
+++ b/src/librustc_mir/dataflow/framework/tests.rs
@@ -223,7 +223,7 @@ impl Analysis<'tcx> for MockAnalysis<'tcx> {
         block: BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _return_place: &mir::Place<'tcx>,
+        _return_place: mir::Place<'tcx>,
     ) {
         let location = self.body.terminator_loc(block);
         let idx = self.effect_at_target(SeekTarget::AfterAssumeCallReturns(location)).unwrap();
diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
index a62e45082cb..6972a81cf1b 100644
--- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs
+++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
@@ -123,7 +123,7 @@ where
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _dest_place: &mir::Place<'tcx>,
+        _dest_place: mir::Place<'tcx>,
     ) {
     }
 }
@@ -160,13 +160,13 @@ where
 
         match rvalue {
             mir::Rvalue::AddressOf(mt, borrowed_place) => {
-                if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, borrowed_place) {
+                if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, *borrowed_place) {
                     self.trans.gen(borrowed_place.local);
                 }
             }
 
             mir::Rvalue::Ref(_, kind, borrowed_place) => {
-                if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, borrowed_place) {
+                if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, *borrowed_place) {
                     self.trans.gen(borrowed_place.local);
                 }
             }
@@ -230,7 +230,7 @@ impl MutBorrow<'mir, 'tcx> {
     /// below. See [rust-lang/unsafe-code-guidelines#134].
     ///
     /// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
-    fn shared_borrow_allows_mutation(&self, place: &Place<'tcx>) -> bool {
+    fn shared_borrow_allows_mutation(&self, place: Place<'tcx>) -> bool {
         !place.ty(self.body, self.tcx).ty.is_freeze(self.tcx, self.param_env, DUMMY_SP)
     }
 }
@@ -238,17 +238,17 @@ impl MutBorrow<'mir, 'tcx> {
 pub trait BorrowAnalysisKind<'tcx> {
     const ANALYSIS_NAME: &'static str;
 
-    fn in_address_of(&self, mt: Mutability, place: &Place<'tcx>) -> bool;
-    fn in_ref(&self, kind: mir::BorrowKind, place: &Place<'tcx>) -> bool;
+    fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool;
+    fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool;
 }
 
 impl BorrowAnalysisKind<'tcx> for AnyBorrow {
     const ANALYSIS_NAME: &'static str = "maybe_borrowed_locals";
 
-    fn in_ref(&self, _: mir::BorrowKind, _: &Place<'_>) -> bool {
+    fn in_ref(&self, _: mir::BorrowKind, _: Place<'_>) -> bool {
         true
     }
-    fn in_address_of(&self, _: Mutability, _: &Place<'_>) -> bool {
+    fn in_address_of(&self, _: Mutability, _: Place<'_>) -> bool {
         true
     }
 }
@@ -256,7 +256,7 @@ impl BorrowAnalysisKind<'tcx> for AnyBorrow {
 impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> {
     const ANALYSIS_NAME: &'static str = "maybe_mut_borrowed_locals";
 
-    fn in_ref(&self, kind: mir::BorrowKind, place: &Place<'tcx>) -> bool {
+    fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool {
         match kind {
             mir::BorrowKind::Mut { .. } => true,
             mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => {
@@ -265,7 +265,7 @@ impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> {
         }
     }
 
-    fn in_address_of(&self, mt: Mutability, place: &Place<'tcx>) -> bool {
+    fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool {
         match mt {
             Mutability::Mut => true,
             Mutability::Not => self.shared_borrow_allows_mutation(place),
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index 6f35d9ac836..0de8f45720e 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -187,7 +187,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
     }
 
     /// Kill any borrows that conflict with `place`.
-    fn kill_borrows_on_place(&self, trans: &mut impl GenKill<BorrowIndex>, place: &Place<'tcx>) {
+    fn kill_borrows_on_place(&self, trans: &mut impl GenKill<BorrowIndex>, place: Place<'tcx>) {
         debug!("kill_borrows_on_place: place={:?}", place);
 
         let other_borrows_of_local = self
@@ -216,7 +216,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
             places_conflict(
                 self.tcx,
                 self.body,
-                &self.borrow_set.borrows[i].borrowed_place,
+                self.borrow_set.borrows[i].borrowed_place,
                 place,
                 PlaceConflictBias::NoOverlap,
             )
@@ -262,8 +262,8 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
         location: Location,
     ) {
         match stmt.kind {
-            mir::StatementKind::Assign(box (ref lhs, ref rhs)) => {
-                if let mir::Rvalue::Ref(_, _, ref place) = *rhs {
+            mir::StatementKind::Assign(box (lhs, ref rhs)) => {
+                if let mir::Rvalue::Ref(_, _, place) = *rhs {
                     if place.ignore_borrow(
                         self.tcx,
                         self.body,
@@ -286,13 +286,13 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
             mir::StatementKind::StorageDead(local) => {
                 // Make sure there are no remaining borrows for locals that
                 // are gone out of scope.
-                self.kill_borrows_on_place(trans, &Place::from(local));
+                self.kill_borrows_on_place(trans, Place::from(local));
             }
 
             mir::StatementKind::LlvmInlineAsm(ref asm) => {
                 for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) {
                     if !kind.is_indirect && !kind.is_rw {
-                        self.kill_borrows_on_place(trans, output);
+                        self.kill_borrows_on_place(trans, *output);
                     }
                 }
             }
@@ -329,7 +329,7 @@ impl<'tcx> dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _dest_place: &mir::Place<'tcx>,
+        _dest_place: mir::Place<'tcx>,
     ) {
     }
 }
diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs
index 3ffa771cb05..1c85226b122 100644
--- a/src/librustc_mir/dataflow/impls/mod.rs
+++ b/src/librustc_mir/dataflow/impls/mod.rs
@@ -323,7 +323,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        dest_place: &mir::Place<'tcx>,
+        dest_place: mir::Place<'tcx>,
     ) {
         // when a call returns successfully, that means we need to set
         // the bits for that dest_place to 1 (initialized).
@@ -342,7 +342,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
         &self,
         trans: &mut impl GenKill<Self::Idx>,
         _block: mir::BasicBlock,
-        enum_place: &mir::Place<'tcx>,
+        enum_place: mir::Place<'tcx>,
         _adt: &ty::AdtDef,
         variant: VariantIdx,
     ) {
@@ -425,7 +425,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        dest_place: &mir::Place<'tcx>,
+        dest_place: mir::Place<'tcx>,
     ) {
         // when a call returns successfully, that means we need to set
         // the bits for that dest_place to 0 (initialized).
@@ -494,7 +494,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
         _block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        dest_place: &mir::Place<'tcx>,
+        dest_place: mir::Place<'tcx>,
     ) {
         // when a call returns successfully, that means we need to set
         // the bits for that dest_place to 1 (initialized).
@@ -585,7 +585,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
         block: mir::BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _dest_place: &mir::Place<'tcx>,
+        _dest_place: mir::Place<'tcx>,
     ) {
         let move_data = self.move_data();
         let init_loc_map = &move_data.init_loc_map;
diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs
index 48dd4e9794c..3dfcfe16fb5 100644
--- a/src/librustc_mir/dataflow/impls/storage_liveness.rs
+++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs
@@ -56,7 +56,7 @@ impl dataflow::GenKillAnalysis<'tcx> for MaybeStorageLive {
         _block: BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        _return_place: &mir::Place<'tcx>,
+        _return_place: mir::Place<'tcx>,
     ) {
         // Nothing to do when a call returns successfully
     }
@@ -231,7 +231,7 @@ impl<'mir, 'tcx> dataflow::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir,
         _block: BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     ) {
         trans.gen(return_place.local);
     }
@@ -240,7 +240,7 @@ impl<'mir, 'tcx> dataflow::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir,
         &self,
         trans: &mut BitSet<Self::Idx>,
         _resume_block: BasicBlock,
-        resume_place: &mir::Place<'tcx>,
+        resume_place: mir::Place<'tcx>,
     ) {
         trans.gen(resume_place.local);
     }
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 1f4455318a4..fabe575c289 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -94,7 +94,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     /// problematic for borrowck.
     ///
     /// Maybe we should have separate "borrowck" and "moveck" modes.
-    fn move_path_for(&mut self, place: &Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
+    fn move_path_for(&mut self, place: Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
         debug!("lookup({:?})", place);
         let mut base = self.builder.data.rev_lookup.locals[place.local];
 
@@ -195,7 +195,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
         })
     }
 
-    fn create_move_path(&mut self, place: &Place<'tcx>) {
+    fn create_move_path(&mut self, place: Place<'tcx>) {
         // This is an non-moving access (such as an overwrite or
         // drop), so this not being a valid move path is OK.
         let _ = self.move_path_for(place);
@@ -279,22 +279,22 @@ struct Gatherer<'b, 'a, 'tcx> {
 
 impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
-        match stmt.kind {
-            StatementKind::Assign(box (ref place, ref rval)) => {
-                self.create_move_path(place);
+        match &stmt.kind {
+            StatementKind::Assign(box (place, rval)) => {
+                self.create_move_path(*place);
                 if let RvalueInitializationState::Shallow = rval.initialization_state() {
                     // Box starts out uninitialized - need to create a separate
                     // move-path for the interior so it will be separate from
                     // the exterior.
-                    self.create_move_path(&self.builder.tcx.mk_place_deref(place.clone()));
+                    self.create_move_path(self.builder.tcx.mk_place_deref(place.clone()));
                     self.gather_init(place.as_ref(), InitKind::Shallow);
                 } else {
                     self.gather_init(place.as_ref(), InitKind::Deep);
                 }
                 self.gather_rvalue(rval);
             }
-            StatementKind::FakeRead(_, ref place) => {
-                self.create_move_path(place);
+            StatementKind::FakeRead(_, place) => {
+                self.create_move_path(**place);
             }
             StatementKind::LlvmInlineAsm(ref asm) => {
                 for (output, kind) in asm.outputs.iter().zip(&asm.asm.outputs) {
@@ -308,7 +308,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             }
             StatementKind::StorageLive(_) => {}
             StatementKind::StorageDead(local) => {
-                self.gather_move(&Place::from(local));
+                self.gather_move(Place::from(*local));
             }
             StatementKind::SetDiscriminant { .. } => {
                 span_bug!(
@@ -369,7 +369,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             | TerminatorKind::Unreachable => {}
 
             TerminatorKind::Return => {
-                self.gather_move(&Place::return_place());
+                self.gather_move(Place::return_place());
             }
 
             TerminatorKind::Assert { ref cond, .. } => {
@@ -380,16 +380,16 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                 self.gather_operand(discr);
             }
 
-            TerminatorKind::Yield { ref value, resume_arg: ref place, .. } => {
+            TerminatorKind::Yield { ref value, resume_arg: place, .. } => {
                 self.gather_operand(value);
                 self.create_move_path(place);
                 self.gather_init(place.as_ref(), InitKind::Deep);
             }
 
-            TerminatorKind::Drop { ref location, target: _, unwind: _ } => {
+            TerminatorKind::Drop { location, target: _, unwind: _ } => {
                 self.gather_move(location);
             }
-            TerminatorKind::DropAndReplace { ref location, ref value, .. } => {
+            TerminatorKind::DropAndReplace { location, ref value, .. } => {
                 self.create_move_path(location);
                 self.gather_operand(value);
                 self.gather_init(location.as_ref(), InitKind::Deep);
@@ -405,7 +405,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                 for arg in args {
                     self.gather_operand(arg);
                 }
-                if let Some((ref destination, _bb)) = *destination {
+                if let Some((destination, _bb)) = *destination {
                     self.create_move_path(destination);
                     self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly);
                 }
@@ -416,14 +416,14 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     fn gather_operand(&mut self, operand: &Operand<'tcx>) {
         match *operand {
             Operand::Constant(..) | Operand::Copy(..) => {} // not-a-move
-            Operand::Move(ref place) => {
+            Operand::Move(place) => {
                 // a move
                 self.gather_move(place);
             }
         }
     }
 
-    fn gather_move(&mut self, place: &Place<'tcx>) {
+    fn gather_move(&mut self, place: Place<'tcx>) {
         debug!("gather_move({:?}, {:?})", self.loc, place);
 
         if let [ref base @ .., ProjectionElem::Subslice { from, to, from_end: false }] =
@@ -434,7 +434,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             // are disjoint, which is expected by drop elaboration.
             let base_place =
                 Place { local: place.local, projection: self.builder.tcx.intern_place_elems(base) };
-            let base_path = match self.move_path_for(&base_place) {
+            let base_path = match self.move_path_for(base_place) {
                 Ok(path) => path,
                 Err(MoveError::UnionMove { path }) => {
                     self.record_move(place, path);
@@ -467,13 +467,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             match self.move_path_for(place) {
                 Ok(path) | Err(MoveError::UnionMove { path }) => self.record_move(place, path),
                 Err(error @ MoveError::IllegalMove { .. }) => {
-                    self.builder.errors.push((*place, error));
+                    self.builder.errors.push((place, error));
                 }
             };
         }
     }
 
-    fn record_move(&mut self, place: &Place<'tcx>, path: MovePathIndex) {
+    fn record_move(&mut self, place: Place<'tcx>, path: MovePathIndex) {
         let move_out = self.builder.data.moves.push(MoveOut { path, source: self.loc });
         debug!(
             "gather_move({:?}, {:?}): adding move {:?} of {:?}",
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 24639fece46..7191198b6c0 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -464,7 +464,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     // avoid allocations.
     pub fn eval_place_to_op(
         &self,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
         layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         let base_op = match place.local {
@@ -498,7 +498,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         use rustc_middle::mir::Operand::*;
         let op = match *mir_op {
             // FIXME: do some more logic on `move` to invalidate the old location
-            Copy(ref place) | Move(ref place) => self.eval_place_to_op(place, layout)?,
+            Copy(place) | Move(place) => self.eval_place_to_op(place, layout)?,
 
             Constant(ref constant) => {
                 let val =
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index f7c1a3cadb8..5c4915d54b0 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -635,7 +635,7 @@ where
     /// place; for reading, a more efficient alternative is `eval_place_for_read`.
     pub fn eval_place(
         &mut self,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
     ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
         let mut place_ty = match place.local {
             mir::RETURN_PLACE => {
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 5fb0a081648..961b0f4d189 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -87,23 +87,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         self.tcx.span = stmt.source_info.span;
         self.memory.tcx.span = stmt.source_info.span;
 
-        match stmt.kind {
-            Assign(box (ref place, ref rvalue)) => self.eval_rvalue_into_place(rvalue, place)?,
+        match &stmt.kind {
+            Assign(box (place, rvalue)) => self.eval_rvalue_into_place(rvalue, *place)?,
 
-            SetDiscriminant { ref place, variant_index } => {
-                let dest = self.eval_place(place)?;
-                self.write_discriminant_index(variant_index, dest)?;
+            SetDiscriminant { place, variant_index } => {
+                let dest = self.eval_place(**place)?;
+                self.write_discriminant_index(*variant_index, dest)?;
             }
 
             // Mark locals as alive
             StorageLive(local) => {
-                let old_val = self.storage_live(local)?;
+                let old_val = self.storage_live(*local)?;
                 self.deallocate_local(old_val)?;
             }
 
             // Mark locals as dead
             StorageDead(local) => {
-                let old_val = self.storage_dead(local);
+                let old_val = self.storage_dead(*local);
                 self.deallocate_local(old_val)?;
             }
 
@@ -112,9 +112,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             FakeRead(..) => {}
 
             // Stacked Borrows.
-            Retag(kind, ref place) => {
-                let dest = self.eval_place(place)?;
-                M::retag(self, kind, dest)?;
+            Retag(kind, place) => {
+                let dest = self.eval_place(**place)?;
+                M::retag(self, *kind, dest)?;
             }
 
             // Statements we do not track.
@@ -138,7 +138,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn eval_rvalue_into_place(
         &mut self,
         rvalue: &mir::Rvalue<'tcx>,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
     ) -> InterpResult<'tcx> {
         let dest = self.eval_place(place)?;
 
@@ -224,7 +224,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
             }
 
-            Len(ref place) => {
+            Len(place) => {
                 // FIXME(CTFE): don't allow computing the length of arrays in const eval
                 let src = self.eval_place(place)?;
                 let mplace = self.force_allocation(src)?;
@@ -232,7 +232,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.write_scalar(Scalar::from_machine_usize(len, self), dest)?;
             }
 
-            AddressOf(_, ref place) | Ref(_, _, ref place) => {
+            AddressOf(_, place) | Ref(_, _, place) => {
                 let src = self.eval_place(place)?;
                 let place = self.force_allocation(src)?;
                 if place.layout.size.bytes() > 0 {
@@ -261,7 +261,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.cast(src, kind, dest)?;
             }
 
-            Discriminant(ref place) => {
+            Discriminant(place) => {
                 let op = self.eval_place_to_op(place, None)?;
                 let discr_val = self.read_discriminant(op)?.0;
                 let size = dest.layout.size;
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 8e7abcd09c2..0c2aa28d811 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -51,7 +51,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.go_to_block(target_block);
             }
 
-            Call { ref func, ref args, ref destination, ref cleanup, .. } => {
+            Call { ref func, ref args, destination, ref cleanup, .. } => {
                 let func = self.eval_operand(func, None)?;
                 let (fn_val, abi) = match func.layout.ty.kind {
                     ty::FnPtr(sig) => {
@@ -68,7 +68,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 };
                 let args = self.eval_operands(args)?;
                 let ret = match destination {
-                    Some((dest, ret)) => Some((self.eval_place(dest)?, *ret)),
+                    Some((dest, ret)) => Some((self.eval_place(dest)?, ret)),
                     None => None,
                 };
                 self.eval_fn_call(
@@ -81,7 +81,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 )?;
             }
 
-            Drop { ref location, target, unwind } => {
+            Drop { location, target, unwind } => {
                 // FIXME(CTFE): forbid drop in const eval
                 let place = self.eval_place(location)?;
                 let ty = place.layout.ty;
@@ -328,7 +328,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     // `pass_argument` would be the loop body. It takes care to
                     // not advance `caller_iter` for ZSTs.
                     for local in body.args_iter() {
-                        let dest = self.eval_place(&mir::Place::from(local))?;
+                        let dest = self.eval_place(mir::Place::from(local))?;
                         if Some(local) == body.spread_arg {
                             // Must be a tuple
                             for i in 0..dest.layout.fields.count() {
@@ -346,7 +346,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     }
                     // Don't forget to check the return type!
                     if let Some((caller_ret, _)) = ret {
-                        let callee_ret = self.eval_place(&mir::Place::return_place())?;
+                        let callee_ret = self.eval_place(mir::Place::return_place())?;
                         if !Self::check_argument_compat(
                             rust_abi,
                             caller_ret.layout,
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 98a95801f1b..0a998bbfe70 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -230,7 +230,7 @@ fn build_drop_shim<'tcx>(
             elaborate_drops::elaborate_drop(
                 &mut elaborator,
                 source_info,
-                &dropee,
+                dropee,
                 (),
                 return_block,
                 elaborate_drops::Unwind::To(resume_block),
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 98a148d60ba..7c46855dfd6 100644
--- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs
+++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs
@@ -68,7 +68,7 @@ fn add_moves_for_packed_drops_patch<'tcx>(
         let terminator = data.terminator();
 
         match terminator.kind {
-            TerminatorKind::Drop { ref location, .. }
+            TerminatorKind::Drop { location, .. }
                 if util::is_disaligned(tcx, body, param_env, location) =>
             {
                 add_move_for_packed_drop(tcx, body, &mut patch, terminator, loc, data.is_cleanup);
diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs
index d39904a56c8..b95a3939389 100644
--- a/src/librustc_mir/transform/check_consts/resolver.rs
+++ b/src/librustc_mir/transform/check_consts/resolver.rs
@@ -68,7 +68,7 @@ where
         _block: BasicBlock,
         _func: &mir::Operand<'tcx>,
         _args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     ) {
         // We cannot reason about another function's internals, so use conservative type-based
         // qualification for the result of a function call.
@@ -76,7 +76,7 @@ where
         let qualif = Q::in_any_value_of_ty(self.item, return_ty);
 
         if !return_place.is_indirect() {
-            self.assign_qualif_direct(return_place, qualif);
+            self.assign_qualif_direct(&return_place, qualif);
         }
     }
 }
@@ -214,7 +214,7 @@ where
         block: BasicBlock,
         func: &mir::Operand<'tcx>,
         args: &[mir::Operand<'tcx>],
-        return_place: &mir::Place<'tcx>,
+        return_place: mir::Place<'tcx>,
     ) {
         self.transfer_function(state).apply_call_return_effect(block, func, args, return_place)
     }
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index c8320a1561a..649cc0a79d6 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/src/librustc_mir/transform/check_consts/validation.rs
@@ -260,7 +260,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
 
         // Special-case reborrows to be more like a copy of a reference.
         match *rvalue {
-            Rvalue::Ref(_, kind, ref place) => {
+            Rvalue::Ref(_, kind, place) => {
                 if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, *self.body, place) {
                     let ctx = match kind {
                         BorrowKind::Shared => {
@@ -281,7 +281,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
                     return;
                 }
             }
-            Rvalue::AddressOf(mutbl, ref place) => {
+            Rvalue::AddressOf(mutbl, place) => {
                 if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, *self.body, place) {
                     let ctx = match mutbl {
                         Mutability::Not => {
@@ -645,7 +645,7 @@ fn check_return_ty_is_sync(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, hir_id: HirId)
 fn place_as_reborrow(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
-    place: &'a Place<'tcx>,
+    place: Place<'tcx>,
 ) -> Option<&'a [PlaceElem<'tcx>]> {
     place.projection.split_last().and_then(|(outermost, inner)| {
         if outermost != &ProjectionElem::Deref {
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index e0ff82b1e64..3ce9b875e16 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -184,14 +184,14 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
         // because either of these would allow modifying the layout constrained field and
         // insert values that violate the layout constraints.
         if context.is_mutating_use() || context.is_borrow() {
-            self.check_mut_borrowing_layout_constrained_field(place, context.is_mutating_use());
+            self.check_mut_borrowing_layout_constrained_field(*place, context.is_mutating_use());
         }
 
         for (i, elem) in place.projection.iter().enumerate() {
             let proj_base = &place.projection[..i];
 
             if context.is_borrow() {
-                if util::is_disaligned(self.tcx, self.body, self.param_env, place) {
+                if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
                     let source_info = self.source_info;
                     let lint_root = self.body.source_scopes[source_info.scope]
                         .local_data
@@ -382,7 +382,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
     }
     fn check_mut_borrowing_layout_constrained_field(
         &mut self,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         is_mut_use: bool,
     ) {
         let mut cursor = place.projection.as_ref();
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index f1ddf3c635f..b51c6141915 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -468,7 +468,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         }
     }
 
-    fn eval_place(&mut self, place: &Place<'tcx>) -> Option<OpTy<'tcx>> {
+    fn eval_place(&mut self, place: Place<'tcx>) -> Option<OpTy<'tcx>> {
         trace!("eval_place(place={:?})", place);
         self.use_ecx(|this| this.ecx.eval_place_to_op(place, None))
     }
@@ -476,7 +476,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
     fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option<OpTy<'tcx>> {
         match *op {
             Operand::Constant(ref c) => self.eval_constant(c, source_info),
-            Operand::Move(ref place) | Operand::Copy(ref place) => self.eval_place(place),
+            Operand::Move(place) | Operand::Copy(place) => self.eval_place(place),
         }
     }
 
@@ -572,7 +572,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         rvalue: &Rvalue<'tcx>,
         place_layout: TyAndLayout<'tcx>,
         source_info: SourceInfo,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
     ) -> Option<()> {
         // #66397: Don't try to eval into large places as that can cause an OOM
         if place_layout.size >= Size::from_bytes(MAX_ALLOC_LIMIT) {
@@ -825,7 +825,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
         trace!("visit_statement: {:?}", statement);
         let source_info = statement.source_info;
         self.source_info = Some(source_info);
-        if let StatementKind::Assign(box (ref place, ref mut rval)) = statement.kind {
+        if let StatementKind::Assign(box (place, ref mut rval)) = statement.kind {
             let place_ty: Ty<'tcx> = place.ty(&self.local_decls, self.tcx).ty;
             if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) {
                 if let Some(local) = place.as_local() {
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index 76cbe5a1d45..a25b554b345 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -97,9 +97,8 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation {
                             if let Some(local) = place.as_local() {
                                 if local == dest_local {
                                     let maybe_action = match operand {
-                                        Operand::Copy(ref src_place)
-                                        | Operand::Move(ref src_place) => {
-                                            Action::local_copy(&body, &def_use_analysis, src_place)
+                                        Operand::Copy(src_place) | Operand::Move(src_place) => {
+                                            Action::local_copy(&body, &def_use_analysis, *src_place)
                                         }
                                         Operand::Constant(ref src_constant) => {
                                             Action::constant(src_constant)
@@ -195,7 +194,7 @@ impl<'tcx> Action<'tcx> {
     fn local_copy(
         body: &Body<'tcx>,
         def_use_analysis: &DefUseAnalysis,
-        src_place: &Place<'tcx>,
+        src_place: Place<'tcx>,
     ) -> Option<Action<'tcx>> {
         // The source must be a local.
         let src_local = if let Some(local) = src_place.as_local() {
diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs
index 30d1613b55c..9933b5cd9f7 100644
--- a/src/librustc_mir/transform/dump_mir.rs
+++ b/src/librustc_mir/transform/dump_mir.rs
@@ -46,7 +46,7 @@ pub fn on_mir_pass<'tcx>(
     body: &Body<'tcx>,
     is_after: bool,
 ) {
-    if mir_util::dump_enabled(tcx, pass_name, source) {
+    if mir_util::dump_enabled(tcx, pass_name, source.def_id()) {
         mir_util::dump_mir(
             tcx,
             Some(pass_num),
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index fc382312aeb..d3971c9a45c 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -346,7 +346,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
 
             let resume_block = self.patch.resume_block();
             match terminator.kind {
-                TerminatorKind::Drop { ref location, target, unwind } => {
+                TerminatorKind::Drop { location, target, unwind } => {
                     self.init_data.seek_before(loc);
                     match self.move_data().rev_lookup.find(location.as_ref()) {
                         LookupResult::Exact(path) => elaborate_drop(
@@ -371,7 +371,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                         }
                     }
                 }
-                TerminatorKind::DropAndReplace { ref location, ref value, target, unwind } => {
+                TerminatorKind::DropAndReplace { location, ref value, target, unwind } => {
                     assert!(!data.is_cleanup);
 
                     self.elaborate_replace(loc, location, value, target, unwind);
@@ -396,7 +396,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     fn elaborate_replace(
         &mut self,
         loc: Location,
-        location: &Place<'tcx>,
+        location: Place<'tcx>,
         value: &Operand<'tcx>,
         target: BasicBlock,
         unwind: Option<BasicBlock>,
@@ -407,7 +407,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
         assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported");
 
         let assign = Statement {
-            kind: StatementKind::Assign(box (*location, Rvalue::Use(value.clone()))),
+            kind: StatementKind::Assign(box (location, Rvalue::Use(value.clone()))),
             source_info: terminator.source_info,
         };
 
@@ -459,7 +459,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                 debug!("elaborate_drop_and_replace({:?}) - untracked {:?}", terminator, parent);
                 self.patch.patch_terminator(
                     bb,
-                    TerminatorKind::Drop { location: *location, target, unwind: Some(unwind) },
+                    TerminatorKind::Drop { location, target, unwind: Some(unwind) },
                 );
             }
         }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 230a835b910..390d927a854 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -853,7 +853,7 @@ fn elaborate_generator_drops<'tcx>(
         elaborate_drop(
             &mut elaborator,
             *source_info,
-            &Place::from(SELF_ARG),
+            Place::from(SELF_ARG),
             (),
             *target,
             unwind,
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 2c27d4c0d27..157dada831a 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -450,7 +450,7 @@ impl Inliner<'tcx> {
                 // Place could result in two different locations if `f`
                 // writes to `i`. To prevent this we need to create a temporary
                 // borrow of the place and pass the destination as `*temp` instead.
-                fn dest_needs_borrow(place: &Place<'_>) -> bool {
+                fn dest_needs_borrow(place: Place<'_>) -> bool {
                     for elem in place.projection.iter() {
                         match elem {
                             ProjectionElem::Deref | ProjectionElem::Index(_) => return true,
@@ -461,7 +461,7 @@ impl Inliner<'tcx> {
                     false
                 }
 
-                let dest = if dest_needs_borrow(&destination.0) {
+                let dest = if dest_needs_borrow(destination.0) {
                     debug!("creating temp for return destination");
                     let dest = Rvalue::Ref(
                         self.tcx.lifetimes.re_erased,
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index 31ffed4cb7b..c5b366ef572 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -150,7 +150,7 @@ fn check_rvalue(
         Rvalue::Len(place)
         | Rvalue::Discriminant(place)
         | Rvalue::Ref(_, _, place)
-        | Rvalue::AddressOf(_, place) => check_place(tcx, place, span, def_id, body),
+        | Rvalue::AddressOf(_, place) => check_place(tcx, *place, span, def_id, body),
         Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
             use rustc_middle::ty::cast::CastTy;
             let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
@@ -215,7 +215,7 @@ fn check_statement(
     let span = statement.source_info.span;
     match &statement.kind {
         StatementKind::Assign(box (place, rval)) => {
-            check_place(tcx, place, span, def_id, body)?;
+            check_place(tcx, *place, span, def_id, body)?;
             check_rvalue(tcx, body, def_id, rval, span)
         }
 
@@ -225,10 +225,12 @@ fn check_statement(
             Err((span, "loops and conditional expressions are not stable in const fn".into()))
         }
 
-        StatementKind::FakeRead(_, place) => check_place(tcx, place, span, def_id, body),
+        StatementKind::FakeRead(_, place) => check_place(tcx, **place, span, def_id, body),
 
         // just an assignment
-        StatementKind::SetDiscriminant { place, .. } => check_place(tcx, place, span, def_id, body),
+        StatementKind::SetDiscriminant { place, .. } => {
+            check_place(tcx, **place, span, def_id, body)
+        }
 
         StatementKind::LlvmInlineAsm { .. } => {
             Err((span, "cannot use inline assembly in const fn".into()))
@@ -251,7 +253,7 @@ fn check_operand(
     body: &Body<'tcx>,
 ) -> McfResult {
     match operand {
-        Operand::Move(place) | Operand::Copy(place) => check_place(tcx, place, span, def_id, body),
+        Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, def_id, body),
         Operand::Constant(c) => match c.check_static_ptr(tcx) {
             Some(_) => Err((span, "cannot access `static` items in const fn".into())),
             None => Ok(()),
@@ -261,7 +263,7 @@ fn check_operand(
 
 fn check_place(
     tcx: TyCtxt<'tcx>,
-    place: &Place<'tcx>,
+    place: Place<'tcx>,
     span: Span,
     def_id: DefId,
     body: &Body<'tcx>,
@@ -330,9 +332,9 @@ fn check_terminator(
         | TerminatorKind::Return
         | TerminatorKind::Resume => Ok(()),
 
-        TerminatorKind::Drop { location, .. } => check_place(tcx, location, span, def_id, body),
+        TerminatorKind::Drop { location, .. } => check_place(tcx, *location, span, def_id, body),
         TerminatorKind::DropAndReplace { location, value, .. } => {
-            check_place(tcx, location, span, def_id, body)?;
+            check_place(tcx, *location, span, def_id, body)?;
             check_operand(tcx, value, span, def_id, body)
         }
 
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 06a697e18da..cccf9ff3016 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -127,7 +127,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>(
                 let loc = Location { block: bb, statement_index };
                 cursor.seek_before(loc);
                 let state = cursor.get();
-                results.analysis.peek_at(tcx, place, state, call);
+                results.analysis.peek_at(tcx, *place, state, call);
             }
 
             _ => {
@@ -231,7 +231,7 @@ pub trait RustcPeekAt<'tcx>: Analysis<'tcx> {
     fn peek_at(
         &self,
         tcx: TyCtxt<'tcx>,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
         flow_state: &BitSet<Self::Idx>,
         call: PeekCall,
     );
@@ -244,7 +244,7 @@ where
     fn peek_at(
         &self,
         tcx: TyCtxt<'tcx>,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
         flow_state: &BitSet<Self::Idx>,
         call: PeekCall,
     ) {
@@ -268,7 +268,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeMutBorrowedLocals<'_, 'tcx> {
     fn peek_at(
         &self,
         tcx: TyCtxt<'tcx>,
-        place: &mir::Place<'tcx>,
+        place: mir::Place<'tcx>,
         flow_state: &BitSet<Local>,
         call: PeekCall,
     ) {
diff --git a/src/librustc_mir/transform/simplify_try.rs b/src/librustc_mir/transform/simplify_try.rs
index fecaee44765..7cdd929c7a0 100644
--- a/src/librustc_mir/transform/simplify_try.rs
+++ b/src/librustc_mir/transform/simplify_try.rs
@@ -89,7 +89,7 @@ fn match_get_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local
         StatementKind::Assign(box (place_into, rvalue_from)) => match rvalue_from {
             Rvalue::Use(Operand::Copy(pf)) | Rvalue::Use(Operand::Move(pf)) => {
                 let local_into = place_into.as_local()?;
-                let (local_from, vf) = match_variant_field_place(&pf)?;
+                let (local_from, vf) = match_variant_field_place(*pf)?;
                 Some((local_into, local_from, vf))
             }
             _ => None,
@@ -107,7 +107,7 @@ fn match_set_variant_field<'tcx>(stmt: &Statement<'tcx>) -> Option<(Local, Local
         StatementKind::Assign(box (place_from, rvalue_into)) => match rvalue_into {
             Rvalue::Use(Operand::Move(place_into)) => {
                 let local_into = place_into.as_local()?;
-                let (local_from, vf) = match_variant_field_place(&place_from)?;
+                let (local_from, vf) = match_variant_field_place(*place_from)?;
                 Some((local_into, local_from, vf))
             }
             _ => None,
@@ -137,7 +137,7 @@ struct VarField<'tcx> {
 }
 
 /// Match on `((_LOCAL as Variant).FIELD: TY)`.
-fn match_variant_field_place<'tcx>(place: &Place<'tcx>) -> Option<(Local, VarField<'tcx>)> {
+fn match_variant_field_place<'tcx>(place: Place<'tcx>) -> Option<(Local, VarField<'tcx>)> {
     match place.as_ref() {
         PlaceRef {
             local,
diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs
index 19c2cfa3a6a..202e5e27f1d 100644
--- a/src/librustc_mir/util/alignment.rs
+++ b/src/librustc_mir/util/alignment.rs
@@ -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/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 7063ed1edc8..f6d67abcef0 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -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 {
@@ -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 {
@@ -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,
@@ -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/liveness.rs b/src/librustc_mir/util/liveness.rs
index 2c6149b9deb..a1b7634f0c6 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -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(|| {
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index bd7725c1b5a..df7df6a0809 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -78,21 +78,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;
     }
 
     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| {
diff --git a/src/librustc_mir_build/build/block.rs b/src/librustc_mir_build/build/block.rs
index 826b3bdcfe5..8c41554bc85 100644
--- a/src/librustc_mir_build/build/block.rs
+++ b/src/librustc_mir_build/build/block.rs
@@ -9,7 +9,7 @@ use rustc_span::Span;
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     crate fn ast_block(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
         ast_block: &'tcx hir::Block<'tcx>,
         source_info: SourceInfo,
@@ -43,7 +43,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
     fn ast_block_stmts(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         mut block: BasicBlock,
         span: Span,
         stmts: Vec<StmtRef<'tcx>>,
diff --git a/src/librustc_mir_build/build/cfg.rs b/src/librustc_mir_build/build/cfg.rs
index f1cb514feaa..f5828c4ac1f 100644
--- a/src/librustc_mir_build/build/cfg.rs
+++ b/src/librustc_mir_build/build/cfg.rs
@@ -34,12 +34,12 @@ impl<'tcx> CFG<'tcx> {
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
         rvalue: Rvalue<'tcx>,
     ) {
         self.push(
             block,
-            Statement { source_info, kind: StatementKind::Assign(box (*place, rvalue)) },
+            Statement { source_info, kind: StatementKind::Assign(box (place, rvalue)) },
         );
     }
 
@@ -47,7 +47,7 @@ impl<'tcx> CFG<'tcx> {
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
-        temp: &Place<'tcx>,
+        temp: Place<'tcx>,
         constant: Constant<'tcx>,
     ) {
         self.push_assign(block, source_info, temp, Rvalue::Use(Operand::Constant(box constant)));
@@ -57,7 +57,7 @@ impl<'tcx> CFG<'tcx> {
         &mut self,
         block: BasicBlock,
         source_info: SourceInfo,
-        place: &Place<'tcx>,
+        place: Place<'tcx>,
     ) {
         self.push_assign(
             block,
diff --git a/src/librustc_mir_build/build/expr/as_place.rs b/src/librustc_mir_build/build/expr/as_place.rs
index 90931a14894..9f74385b336 100644
--- a/src/librustc_mir_build/build/expr/as_place.rs
+++ b/src/librustc_mir_build/build/expr/as_place.rs
@@ -341,12 +341,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let lt = self.temp(bool_ty, expr_span);
 
         // len = len(slice)
-        self.cfg.push_assign(block, source_info, &len, Rvalue::Len(slice));
+        self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice));
         // lt = idx < len
         self.cfg.push_assign(
             block,
             source_info,
-            &lt,
+            lt,
             Rvalue::BinaryOp(BinOp::Lt, Operand::Copy(Place::from(index)), Operand::Copy(len)),
         );
         let msg = BoundsCheck { len: Operand::Move(len), index: Operand::Copy(Place::from(index)) };
@@ -388,7 +388,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         self.cfg.push_assign(
                             block,
                             source_info,
-                            &fake_borrow_temp.into(),
+                            fake_borrow_temp.into(),
                             Rvalue::Ref(
                                 tcx.lifetimes.re_erased,
                                 BorrowKind::Shallow,
diff --git a/src/librustc_mir_build/build/expr/as_rvalue.rs b/src/librustc_mir_build/build/expr/as_rvalue.rs
index 96d6ca1ecab..20ef763e90c 100644
--- a/src/librustc_mir_build/build/expr/as_rvalue.rs
+++ b/src/librustc_mir_build/build/expr/as_rvalue.rs
@@ -78,7 +78,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     this.cfg.push_assign(
                         block,
                         source_info,
-                        &is_min,
+                        is_min,
                         Rvalue::BinaryOp(BinOp::Eq, arg.to_copy(), minval),
                     );
 
@@ -109,15 +109,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                 // malloc some memory of suitable type (thus far, uninitialized):
                 let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
-                this.cfg.push_assign(block, source_info, &Place::from(result), box_);
+                this.cfg.push_assign(block, source_info, Place::from(result), box_);
 
                 // initialize the box contents:
                 unpack!(
-                    block = this.into(
-                        &this.hir.tcx().mk_place_deref(Place::from(result)),
-                        block,
-                        value
-                    )
+                    block =
+                        this.into(this.hir.tcx().mk_place_deref(Place::from(result)), block, value)
                 );
                 block.and(Rvalue::Use(Operand::Move(Place::from(result))))
             }
@@ -284,7 +281,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             self.cfg.push_assign(
                 block,
                 source_info,
-                &result_value,
+                result_value,
                 Rvalue::CheckedBinaryOp(op, lhs, rhs),
             );
             let val_fld = Field::new(0);
@@ -317,7 +314,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 self.cfg.push_assign(
                     block,
                     source_info,
-                    &is_zero,
+                    is_zero,
                     Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), zero),
                 );
 
@@ -338,13 +335,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &is_neg_1,
+                        is_neg_1,
                         Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), neg_1),
                     );
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &is_min,
+                        is_min,
                         Rvalue::BinaryOp(BinOp::Eq, lhs.to_copy(), min),
                     );
 
@@ -353,7 +350,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &of,
+                        of,
                         Rvalue::BinaryOp(BinOp::BitAnd, is_neg_1, is_min),
                     );
 
@@ -428,7 +425,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         this.cfg.push_assign(
             block,
             source_info,
-            &Place::from(temp),
+            Place::from(temp),
             Rvalue::Ref(this.hir.tcx().lifetimes.re_erased, borrow_kind, arg_place),
         );
 
diff --git a/src/librustc_mir_build/build/expr/as_temp.rs b/src/librustc_mir_build/build/expr/as_temp.rs
index ef692079e0c..73d95575e39 100644
--- a/src/librustc_mir_build/build/expr/as_temp.rs
+++ b/src/librustc_mir_build/build/expr/as_temp.rs
@@ -66,7 +66,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             this.local_decls.push(local_decl)
         };
-        let temp_place = &Place::from(temp);
+        let temp_place = Place::from(temp);
 
         match expr.kind {
             // Don't bother with StorageLive and Dead for these temporaries,
diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs
index c61526024d0..6b93755e9da 100644
--- a/src/librustc_mir_build/build/expr/into.rs
+++ b/src/librustc_mir_build/build/expr/into.rs
@@ -16,7 +16,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// is assumed to be uninitialized.
     crate fn into_expr(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         mut block: BasicBlock,
         expr: Expr<'tcx>,
     ) -> BlockAnd<()> {
@@ -160,7 +160,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         // introduce a unit temporary as the destination for the loop body.
                         let tmp = this.get_unit_temp();
                         // Execute the body, branching back to the test.
-                        let body_block_end = unpack!(this.into(&tmp, body_block, body));
+                        let body_block_end = unpack!(this.into(tmp, body_block, body));
                         this.cfg.goto(body_block_end, source_info, loop_block);
                     },
                 );
@@ -202,8 +202,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         is_block_tail: None,
                     });
                     let ptr_temp = Place::from(ptr_temp);
-                    let block = unpack!(this.into(&ptr_temp, block, ptr));
-                    this.into(&this.hir.tcx().mk_place_deref(ptr_temp), block, val)
+                    let block = unpack!(this.into(ptr_temp, block, ptr));
+                    this.into(this.hir.tcx().mk_place_deref(ptr_temp), block, val)
                 } else {
                     let args: Vec<_> = args
                         .into_iter()
@@ -228,7 +228,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             destination: if expr.ty.is_never() {
                                 None
                             } else {
-                                Some((*destination, success))
+                                Some((destination, success))
                             },
                             from_hir_call,
                         },
@@ -373,12 +373,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 this.cfg.terminate(
                     block,
                     source_info,
-                    TerminatorKind::Yield {
-                        value,
-                        resume,
-                        resume_arg: *destination,
-                        drop: cleanup,
-                    },
+                    TerminatorKind::Yield { value, resume, resume_arg: destination, drop: cleanup },
                 );
                 resume.unit()
             }
diff --git a/src/librustc_mir_build/build/expr/stmt.rs b/src/librustc_mir_build/build/expr/stmt.rs
index 8bfd2ce36bb..92e1e105185 100644
--- a/src/librustc_mir_build/build/expr/stmt.rs
+++ b/src/librustc_mir_build/build/expr/stmt.rs
@@ -50,7 +50,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 } else {
                     let rhs = unpack!(block = this.as_local_rvalue(block, rhs));
                     let lhs = unpack!(block = this.as_place(block, lhs));
-                    this.cfg.push_assign(block, source_info, &lhs, rhs);
+                    this.cfg.push_assign(block, source_info, lhs, rhs);
                 }
 
                 this.block_context.pop();
@@ -82,7 +82,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     block =
                         this.build_binary_op(block, op, expr_span, lhs_ty, Operand::Copy(lhs), rhs)
                 );
-                this.cfg.push_assign(block, source_info, &lhs, result);
+                this.cfg.push_assign(block, source_info, lhs, result);
 
                 this.block_context.pop();
                 block.unit()
diff --git a/src/librustc_mir_build/build/into.rs b/src/librustc_mir_build/build/into.rs
index 1c0981597d3..0baa0c833a5 100644
--- a/src/librustc_mir_build/build/into.rs
+++ b/src/librustc_mir_build/build/into.rs
@@ -12,7 +12,7 @@ pub(in crate::build) trait EvalInto<'tcx> {
     fn eval_into(
         self,
         builder: &mut Builder<'_, 'tcx>,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
     ) -> BlockAnd<()>;
 }
@@ -20,7 +20,7 @@ pub(in crate::build) trait EvalInto<'tcx> {
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     crate fn into<E>(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
         expr: E,
     ) -> BlockAnd<()>
@@ -35,7 +35,7 @@ impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
     fn eval_into(
         self,
         builder: &mut Builder<'_, 'tcx>,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
     ) -> BlockAnd<()> {
         let expr = builder.hir.mirror(self);
@@ -47,7 +47,7 @@ impl<'tcx> EvalInto<'tcx> for Expr<'tcx> {
     fn eval_into(
         self,
         builder: &mut Builder<'_, 'tcx>,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         block: BasicBlock,
     ) -> BlockAnd<()> {
         builder.into_expr(destination, block, self)
diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs
index d205ce254d3..a98b18c0cf1 100644
--- a/src/librustc_mir_build/build/matches/mod.rs
+++ b/src/librustc_mir_build/build/matches/mod.rs
@@ -10,16 +10,16 @@ use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard};
 use crate::build::{BlockAnd, BlockAndExtension, Builder};
 use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode};
 use crate::hair::{self, *};
+use rustc_ast::ast::Name;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_hir::HirId;
+use rustc_index::bit_set::BitSet;
 use rustc_middle::middle::region;
 use rustc_middle::mir::*;
 use rustc_middle::ty::layout::VariantIdx;
 use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir::HirId;
-use rustc_index::bit_set::BitSet;
 use rustc_span::Span;
 use smallvec::{smallvec, SmallVec};
-use rustc_ast::ast::Name;
 
 // helper functions, broken out by category:
 mod simplify;
@@ -83,7 +83,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// * From each otherwise block to the next prebinding block.
     crate fn match_expr(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         span: Span,
         mut block: BasicBlock,
         scrutinee: ExprRef<'tcx>,
@@ -218,7 +218,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// `outer_source_info` is the SourceInfo for the whole match.
     fn lower_match_arms(
         &mut self,
-        destination: &Place<'tcx>,
+        destination: Place<'tcx>,
         scrutinee_place: Place<'tcx>,
         scrutinee_span: Span,
         arm_candidates: Vec<(&'_ Arm<'tcx>, Candidate<'_, 'tcx>)>,
@@ -364,7 +364,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             PatKind::Binding { mode: BindingMode::ByValue, var, subpattern: None, .. } => {
                 let place =
                     self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
-                unpack!(block = self.into(&place, block, initializer));
+                unpack!(block = self.into(place, block, initializer));
 
                 // Inject a fake read, see comments on `FakeReadCause::ForLet`.
                 let source_info = self.source_info(irrefutable_pat.span);
@@ -399,7 +399,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             } => {
                 let place =
                     self.storage_live_binding(block, var, irrefutable_pat.span, OutsideGuard, true);
-                unpack!(block = self.into(&place, block, initializer));
+                unpack!(block = self.into(place, block, initializer));
 
                 // Inject a fake read, see comments on `FakeReadCause::ForLet`.
                 let pattern_source_info = self.source_info(irrefutable_pat.span);
@@ -1691,7 +1691,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             let scrutinee_source_info = self.source_info(scrutinee_span);
             for &(place, temp) in fake_borrows {
                 let borrow = Rvalue::Ref(re_erased, BorrowKind::Shallow, place);
-                self.cfg.push_assign(block, scrutinee_source_info, &Place::from(temp), borrow);
+                self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow);
             }
 
             // the block to branch to if the guard fails; if there is no
@@ -1858,7 +1858,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             match binding.binding_mode {
                 BindingMode::ByValue => {
                     let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, binding.source);
-                    self.cfg.push_assign(block, source_info, &ref_for_guard, rvalue);
+                    self.cfg.push_assign(block, source_info, ref_for_guard, rvalue);
                 }
                 BindingMode::ByRef(borrow_kind) => {
                     let value_for_arm = self.storage_live_binding(
@@ -1870,9 +1870,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     );
 
                     let rvalue = Rvalue::Ref(re_erased, borrow_kind, binding.source);
-                    self.cfg.push_assign(block, source_info, &value_for_arm, rvalue);
+                    self.cfg.push_assign(block, source_info, value_for_arm, rvalue);
                     let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, value_for_arm);
-                    self.cfg.push_assign(block, source_info, &ref_for_guard, rvalue);
+                    self.cfg.push_assign(block, source_info, ref_for_guard, rvalue);
                 }
             }
         }
@@ -1910,7 +1910,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     Rvalue::Ref(re_erased, borrow_kind, binding.source)
                 }
             };
-            self.cfg.push_assign(block, source_info, &local, rvalue);
+            self.cfg.push_assign(block, source_info, local, rvalue);
         }
     }
 
diff --git a/src/librustc_mir_build/build/matches/test.rs b/src/librustc_mir_build/build/matches/test.rs
index 01b3cfb7ba0..450bb0a861d 100644
--- a/src/librustc_mir_build/build/matches/test.rs
+++ b/src/librustc_mir_build/build/matches/test.rs
@@ -202,7 +202,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 );
                 let discr_ty = adt_def.repr.discr_type().to_ty(tcx);
                 let discr = self.temp(discr_ty, test.span);
-                self.cfg.push_assign(block, source_info, &discr, Rvalue::Discriminant(place));
+                self.cfg.push_assign(block, source_info, discr, Rvalue::Discriminant(place));
                 assert_eq!(values.len() + 1, targets.len());
                 self.cfg.terminate(
                     block,
@@ -303,7 +303,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let actual = self.temp(usize_ty, test.span);
 
                 // actual = len(place)
-                self.cfg.push_assign(block, source_info, &actual, Rvalue::Len(place));
+                self.cfg.push_assign(block, source_info, actual, Rvalue::Len(place));
 
                 // expected = <N>
                 let expected = self.push_usize(block, source_info, len);
@@ -342,7 +342,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let result = self.temp(bool_ty, source_info.span);
 
         // result = op(left, right)
-        self.cfg.push_assign(block, source_info, &result, Rvalue::BinaryOp(op, left, right));
+        self.cfg.push_assign(block, source_info, result, Rvalue::BinaryOp(op, left, right));
 
         // branch based on result
         self.cfg.terminate(
@@ -394,7 +394,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &temp,
+                        temp,
                         Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), val, ty),
                     );
                     val = Operand::Move(temp);
@@ -404,7 +404,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.cfg.push_assign(
                         block,
                         source_info,
-                        &slice,
+                        slice,
                         Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), expect, ty),
                     );
                     expect = Operand::Move(slice);
diff --git a/src/librustc_mir_build/build/misc.rs b/src/librustc_mir_build/build/misc.rs
index 06371d71b9d..8f98dd9b70e 100644
--- a/src/librustc_mir_build/build/misc.rs
+++ b/src/librustc_mir_build/build/misc.rs
@@ -55,7 +55,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         self.cfg.push_assign_constant(
             block,
             source_info,
-            &temp,
+            temp,
             Constant {
                 span: source_info.span,
                 user_ty: None,
diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs
index c4eb9803b42..cec7e5bc199 100644
--- a/src/librustc_mir_build/build/mod.rs
+++ b/src/librustc_mir_build/build/mod.rs
@@ -663,7 +663,7 @@ fn construct_const<'a, 'tcx>(
     let mut block = START_BLOCK;
     let ast_expr = &tcx.hir().body(body_id).value;
     let expr = builder.hir.mirror(ast_expr);
-    unpack!(block = builder.into_expr(&Place::return_place(), block, expr));
+    unpack!(block = builder.into_expr(Place::return_place(), block, expr));
 
     let source_info = builder.source_info(span);
     builder.cfg.terminate(block, source_info, TerminatorKind::Return);
@@ -969,7 +969,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
 
         let body = self.hir.mirror(ast_body);
-        self.into(&Place::return_place(), block, body)
+        self.into(Place::return_place(), block, body)
     }
 
     fn set_correct_source_scope_for_arg(
diff --git a/src/librustc_mir_build/build/scope.rs b/src/librustc_mir_build/build/scope.rs
index be34c84f124..3689e5cb9d8 100644
--- a/src/librustc_mir_build/build/scope.rs
+++ b/src/librustc_mir_build/build/scope.rs
@@ -520,10 +520,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             if let Some(value) = value {
                 debug!("stmt_expr Break val block_context.push(SubExpr)");
                 self.block_context.push(BlockFrame::SubExpr);
-                unpack!(block = self.into(&destination, block, value));
+                unpack!(block = self.into(destination, block, value));
                 self.block_context.pop();
             } else {
-                self.cfg.push_assign_unit(block, source_info, &destination)
+                self.cfg.push_assign_unit(block, source_info, destination)
             }
         } else {
             assert!(value.is_none(), "`return` and `break` should have a destination");
diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs
index c7ea10ec812..96321ef2145 100644
--- a/src/librustc_parse/lexer/mod.rs
+++ b/src/librustc_parse/lexer/mod.rs
@@ -1,20 +1,20 @@
 use rustc_ast::token::{self, Token, TokenKind};
 use rustc_ast::util::comments;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{error_code, DiagnosticBuilder, FatalError};
-use rustc_lexer::unescape;
+use rustc_errors::{error_code, Applicability, DiagnosticBuilder, FatalError};
 use rustc_lexer::Base;
+use rustc_lexer::{unescape, LexRawStrError, UnvalidatedRawStr, ValidatedRawStr};
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{BytePos, Pos, Span};
 
 use log::debug;
 use std::char;
-use std::convert::TryInto;
 
 mod tokentrees;
 mod unescape_error_reporting;
 mod unicode_chars;
+
 use unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
 #[derive(Clone, Debug)]
@@ -373,30 +373,22 @@ impl<'a> StringReader<'a> {
                 let id = self.symbol_from_to(content_start, content_end);
                 (token::ByteStr, id)
             }
-            rustc_lexer::LiteralKind::RawStr { n_hashes, started, terminated } => {
-                if !started {
-                    self.report_non_started_raw_string(start);
-                }
-                if !terminated {
-                    self.report_unterminated_raw_string(start, n_hashes)
-                }
-                let n_hashes: u16 = self.restrict_n_hashes(start, n_hashes);
+            rustc_lexer::LiteralKind::RawStr(unvalidated_raw_str) => {
+                let valid_raw_str = self.validate_and_report_errors(start, unvalidated_raw_str);
+                let n_hashes = valid_raw_str.num_hashes();
                 let n = u32::from(n_hashes);
+
                 let content_start = start + BytePos(2 + n);
                 let content_end = suffix_start - BytePos(1 + n);
                 self.validate_raw_str_escape(content_start, content_end);
                 let id = self.symbol_from_to(content_start, content_end);
                 (token::StrRaw(n_hashes), id)
             }
-            rustc_lexer::LiteralKind::RawByteStr { n_hashes, started, terminated } => {
-                if !started {
-                    self.report_non_started_raw_string(start);
-                }
-                if !terminated {
-                    self.report_unterminated_raw_string(start, n_hashes)
-                }
-                let n_hashes: u16 = self.restrict_n_hashes(start, n_hashes);
+            rustc_lexer::LiteralKind::RawByteStr(unvalidated_raw_str) => {
+                let validated_raw_str = self.validate_and_report_errors(start, unvalidated_raw_str);
+                let n_hashes = validated_raw_str.num_hashes();
                 let n = u32::from(n_hashes);
+
                 let content_start = start + BytePos(3 + n);
                 let content_end = suffix_start - BytePos(1 + n);
                 self.validate_raw_byte_str_escape(content_start, content_end);
@@ -482,6 +474,26 @@ impl<'a> StringReader<'a> {
         }
     }
 
+    fn validate_and_report_errors(
+        &self,
+        start: BytePos,
+        unvalidated_raw_str: UnvalidatedRawStr,
+    ) -> ValidatedRawStr {
+        match unvalidated_raw_str.validate() {
+            Err(LexRawStrError::InvalidStarter) => self.report_non_started_raw_string(start),
+            Err(LexRawStrError::NoTerminator { expected, found, possible_terminator_offset }) => {
+                self.report_unterminated_raw_string(
+                    start,
+                    expected,
+                    possible_terminator_offset,
+                    found,
+                )
+            }
+            Err(LexRawStrError::TooManyDelimiters) => self.report_too_many_hashes(start),
+            Ok(valid) => valid,
+        }
+    }
+
     fn report_non_started_raw_string(&self, start: BytePos) -> ! {
         let bad_char = self.str_from(start).chars().last().unwrap();
         self.struct_fatal_span_char(
@@ -495,38 +507,51 @@ impl<'a> StringReader<'a> {
         FatalError.raise()
     }
 
-    fn report_unterminated_raw_string(&self, start: BytePos, n_hashes: usize) -> ! {
+    fn report_unterminated_raw_string(
+        &self,
+        start: BytePos,
+        n_hashes: usize,
+        possible_offset: Option<usize>,
+        found_terminators: usize,
+    ) -> ! {
         let mut err = self.sess.span_diagnostic.struct_span_fatal_with_code(
             self.mk_sp(start, start),
             "unterminated raw string",
             error_code!(E0748),
         );
+
         err.span_label(self.mk_sp(start, start), "unterminated raw string");
 
         if n_hashes > 0 {
             err.note(&format!(
                 "this raw string should be terminated with `\"{}`",
-                "#".repeat(n_hashes as usize)
+                "#".repeat(n_hashes)
             ));
         }
 
+        if let Some(possible_offset) = possible_offset {
+            let lo = start + BytePos(possible_offset as u32);
+            let hi = lo + BytePos(found_terminators as u32);
+            let span = self.mk_sp(lo, hi);
+            err.span_suggestion(
+                span,
+                "consider terminating the string here",
+                "#".repeat(n_hashes),
+                Applicability::MaybeIncorrect,
+            );
+        }
+
         err.emit();
         FatalError.raise()
     }
 
-    fn restrict_n_hashes(&self, start: BytePos, n_hashes: usize) -> u16 {
-        match n_hashes.try_into() {
-            Ok(n_hashes) => n_hashes,
-            Err(_) => {
-                self.fatal_span_(
-                    start,
-                    self.pos,
-                    "too many `#` symbols: raw strings may be \
-                                  delimited by up to 65535 `#` symbols",
-                )
-                .raise();
-            }
-        }
+    fn report_too_many_hashes(&self, start: BytePos) -> ! {
+        self.fatal_span_(
+            start,
+            self.pos,
+            "too many `#` symbols: raw strings may be delimited by up to 65535 `#` symbols",
+        )
+        .raise();
     }
 
     fn validate_char_escape(&self, content_start: BytePos, content_end: BytePos) {
diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs
index 13fb85db847..8e2a9513d6b 100644
--- a/src/librustc_parse/lib.rs
+++ b/src/librustc_parse/lib.rs
@@ -4,6 +4,7 @@
 #![feature(crate_visibility_modifier)]
 #![feature(bindings_after_at)]
 #![feature(try_blocks)]
+#![feature(or_patterns)]
 
 use rustc_ast::ast;
 use rustc_ast::token::{self, Nonterminal};
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index c4546dedfcd..12b9b682682 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -6,7 +6,7 @@ use rustc_ast::ast::{
 };
 use rustc_ast::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind};
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, TokenKind};
+use rustc_ast::token::{self, Lit, LitKind, TokenKind};
 use rustc_ast::util::parser::AssocOp;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
@@ -255,6 +255,10 @@ impl<'a> Parser<'a> {
             }
         }
 
+        if self.check_too_many_raw_str_terminators(&mut err) {
+            return Err(err);
+        }
+
         let sm = self.sess.source_map();
         if self.prev_token.span == DUMMY_SP {
             // Account for macro context where the previous span might not be
@@ -282,6 +286,29 @@ impl<'a> Parser<'a> {
         Err(err)
     }
 
+    fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool {
+        match (&self.prev_token.kind, &self.token.kind) {
+            (
+                TokenKind::Literal(Lit {
+                    kind: LitKind::StrRaw(n_hashes) | LitKind::ByteStrRaw(n_hashes),
+                    ..
+                }),
+                TokenKind::Pound,
+            ) => {
+                err.set_primary_message("too many `#` when terminating raw string");
+                err.span_suggestion(
+                    self.token.span,
+                    "remove the extra `#`",
+                    String::new(),
+                    Applicability::MachineApplicable,
+                );
+                err.note(&format!("the raw string started with {} `#`s", n_hashes));
+                true
+            }
+            _ => false,
+        }
+    }
+
     pub fn maybe_annotate_with_ascription(
         &mut self,
         err: &mut DiagnosticBuilder<'_>,
@@ -491,7 +518,7 @@ impl<'a> Parser<'a> {
                             .unwrap_or_else(|_| pprust::expr_to_string(&e))
                     };
                     err.span_suggestion_verbose(
-                            inner_op.span.shrink_to_hi(),
+                        inner_op.span.shrink_to_hi(),
                         "split the comparison into two",
                         format!(" && {}", expr_to_str(&r1)),
                         Applicability::MaybeIncorrect,
@@ -1086,7 +1113,7 @@ impl<'a> Parser<'a> {
             self.look_ahead(2, |t| t.is_ident())
             || self.look_ahead(1, |t| t == &token::ModSep)
                 && (self.look_ahead(2, |t| t.is_ident()) ||   // `foo:bar::baz`
-             self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::<baz>`
+            self.look_ahead(2, |t| t == &token::Lt)) // `foo:bar::<baz>`
     }
 
     pub(super) fn recover_seq_parse_error(
diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs
index e43908a7914..432f1e17ab3 100644
--- a/src/librustc_session/options.rs
+++ b/src/librustc_session/options.rs
@@ -835,6 +835,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "the directory the MIR is dumped into"),
     dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED],
         "in addition to `.mir` files, create graphviz `.dot` files"),
+    dump_mir_dataflow: bool = (false, parse_bool, [UNTRACKED],
+        "in addition to `.mir` files, create graphviz `.dot` files with dataflow results"),
     dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED],
         "if set, exclude the pass number when dumping MIR (used in tests)"),
     mir_emit_retag: bool = (false, parse_bool, [TRACKED],
diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs
index ffc85c153c9..72768c31e30 100644
--- a/src/librustc_target/abi/call/mod.rs
+++ b/src/librustc_target/abi/call/mod.rs
@@ -546,6 +546,8 @@ pub struct FnAbi<'a, Ty> {
     pub fixed_count: usize,
 
     pub conv: Conv,
+
+    pub can_unwind: bool,
 }
 
 impl<'a, Ty> FnAbi<'a, Ty> {
diff --git a/src/test/ui/parser/raw-str-unbalanced.rs b/src/test/ui/parser/raw-str-unbalanced.rs
deleted file mode 100644
index 5a1d1be11b6..00000000000
--- a/src/test/ui/parser/raw-str-unbalanced.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-static s: &'static str =
-    r#"
-      "## //~ ERROR expected one of `.`, `;`, `?`, or an operator, found `#`
-;
diff --git a/src/test/ui/parser/raw-str-unbalanced.stderr b/src/test/ui/parser/raw-str-unbalanced.stderr
deleted file mode 100644
index ddb75722bef..00000000000
--- a/src/test/ui/parser/raw-str-unbalanced.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected one of `.`, `;`, `?`, or an operator, found `#`
-  --> $DIR/raw-str-unbalanced.rs:3:9
-   |
-LL |       "##
-   |         ^ expected one of `.`, `;`, `?`, or an operator
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/parser/raw-byte-string-eof.rs b/src/test/ui/parser/raw/raw-byte-string-eof.rs
index b74907b72b0..b74907b72b0 100644
--- a/src/test/ui/parser/raw-byte-string-eof.rs
+++ b/src/test/ui/parser/raw/raw-byte-string-eof.rs
diff --git a/src/test/ui/parser/raw-byte-string-eof.stderr b/src/test/ui/parser/raw/raw-byte-string-eof.stderr
index d5f22e2a1a8..a76668e8051 100644
--- a/src/test/ui/parser/raw-byte-string-eof.stderr
+++ b/src/test/ui/parser/raw/raw-byte-string-eof.stderr
@@ -2,7 +2,9 @@ error[E0748]: unterminated raw string
   --> $DIR/raw-byte-string-eof.rs:2:5
    |
 LL |     br##"a"#;
-   |     ^ unterminated raw string
+   |     ^      - help: consider terminating the string here: `##`
+   |     |
+   |     unterminated raw string
    |
    = note: this raw string should be terminated with `"##`
 
diff --git a/src/test/ui/parser/raw-byte-string-literals.rs b/src/test/ui/parser/raw/raw-byte-string-literals.rs
index 163c8ac66b0..163c8ac66b0 100644
--- a/src/test/ui/parser/raw-byte-string-literals.rs
+++ b/src/test/ui/parser/raw/raw-byte-string-literals.rs
diff --git a/src/test/ui/parser/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr
index 4076fe334e6..4076fe334e6 100644
--- a/src/test/ui/parser/raw-byte-string-literals.stderr
+++ b/src/test/ui/parser/raw/raw-byte-string-literals.stderr
diff --git a/src/test/ui/parser/raw-str-delim.rs b/src/test/ui/parser/raw/raw-str-delim.rs
index 2f13893cecd..2f13893cecd 100644
--- a/src/test/ui/parser/raw-str-delim.rs
+++ b/src/test/ui/parser/raw/raw-str-delim.rs
diff --git a/src/test/ui/parser/raw-str-delim.stderr b/src/test/ui/parser/raw/raw-str-delim.stderr
index 8a04f99a126..8a04f99a126 100644
--- a/src/test/ui/parser/raw-str-delim.stderr
+++ b/src/test/ui/parser/raw/raw-str-delim.stderr
diff --git a/src/test/ui/parser/raw/raw-str-in-macro-call.rs b/src/test/ui/parser/raw/raw-str-in-macro-call.rs
new file mode 100644
index 00000000000..462c2279f5c
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-in-macro-call.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+macro_rules! m1 {
+    ($tt:tt #) => ()
+}
+
+macro_rules! m2 {
+    ($tt:tt) => ()
+}
+
+fn main() {
+    m1!(r#"abc"##);
+    m2!(r#"abc"#);
+}
diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.rs b/src/test/ui/parser/raw/raw-str-unbalanced.rs
new file mode 100644
index 00000000000..35f118f5ce6
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-unbalanced.rs
@@ -0,0 +1,4 @@
+static s: &'static str =
+    r#"
+      "## //~ too many `#` when terminating raw string
+;
diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.stderr b/src/test/ui/parser/raw/raw-str-unbalanced.stderr
new file mode 100644
index 00000000000..bf8f3a7a5a4
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-str-unbalanced.stderr
@@ -0,0 +1,10 @@
+error: too many `#` when terminating raw string
+  --> $DIR/raw-str-unbalanced.rs:3:9
+   |
+LL |       "##
+   |         ^ help: remove the extra `#`
+   |
+   = note: the raw string started with 1 `#`s
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/raw-str-unterminated.rs b/src/test/ui/parser/raw/raw-str-unterminated.rs
index fd317295561..fd317295561 100644
--- a/src/test/ui/parser/raw-str-unterminated.rs
+++ b/src/test/ui/parser/raw/raw-str-unterminated.rs
diff --git a/src/test/ui/parser/raw-str-unterminated.stderr b/src/test/ui/parser/raw/raw-str-unterminated.stderr
index 077f763f154..077f763f154 100644
--- a/src/test/ui/parser/raw-str-unterminated.stderr
+++ b/src/test/ui/parser/raw/raw-str-unterminated.stderr
diff --git a/src/test/ui/parser/raw/raw-string-2.rs b/src/test/ui/parser/raw/raw-string-2.rs
new file mode 100644
index 00000000000..067332d2819
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-string-2.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let x = r###"here's a long string"# "# "##;
+    //~^ ERROR unterminated raw string
+}
diff --git a/src/test/ui/parser/raw/raw-string-2.stderr b/src/test/ui/parser/raw/raw-string-2.stderr
new file mode 100644
index 00000000000..8bbac9d7bd0
--- /dev/null
+++ b/src/test/ui/parser/raw/raw-string-2.stderr
@@ -0,0 +1,11 @@
+error[E0748]: unterminated raw string
+  --> $DIR/raw-string-2.rs:2:13
+   |
+LL |     let x = r###"here's a long string"# "# "##;
+   |             ^ unterminated raw string       -- help: consider terminating the string here: `###`
+   |
+   = note: this raw string should be terminated with `"###`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0748`.
diff --git a/src/test/ui/parser/raw/raw_string.rs b/src/test/ui/parser/raw/raw-string.rs
index 84f07c4a941..84f07c4a941 100644
--- a/src/test/ui/parser/raw/raw_string.rs
+++ b/src/test/ui/parser/raw/raw-string.rs
diff --git a/src/test/ui/parser/raw/raw_string.stderr b/src/test/ui/parser/raw/raw-string.stderr
index 0f1d7e4651d..b2b853a89e7 100644
--- a/src/test/ui/parser/raw/raw_string.stderr
+++ b/src/test/ui/parser/raw/raw-string.stderr
@@ -1,8 +1,10 @@
 error[E0748]: unterminated raw string
-  --> $DIR/raw_string.rs:2:13
+  --> $DIR/raw-string.rs:2:13
    |
 LL |     let x = r##"lol"#;
-   |             ^ unterminated raw string
+   |             ^       - help: consider terminating the string here: `##`
+   |             |
+   |             unterminated raw string
    |
    = note: this raw string should be terminated with `"##`