about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-17 14:23:57 +0000
committerbors <bors@rust-lang.org>2018-04-17 14:23:57 +0000
commit881a7cd86ef1001bdfa9590878ca24e57794302f (patch)
tree947639046e0b0f2a1ddc5d0ad6d6f4e33040ff44
parentd703622ce08d51eb91a909278f7917762e743438 (diff)
parent96dba9358c5ad24bc33eeb3a9a39a4868c331bcf (diff)
downloadrust-881a7cd86ef1001bdfa9590878ca24e57794302f.tar.gz
rust-881a7cd86ef1001bdfa9590878ca24e57794302f.zip
Auto merge of #49836 - nikomatsakis:nll-facts-prep, r=pnkfelix
prep work for using timely dataflow with NLL

Two major changes:

**Two-phase borrows are overhauled.** We no longer have two bits per borrow. Instead, we track -- for each borrow -- an (optional) "activation point". Then, for each point P where the borrow is in scope, we check where P falls relative to the activation point. If P is between the reservation point and the activation point, then this is the "reservation" phase of the borrow, else the borrow is considered active. This is simpler and means that the dataflow doesn't have to care about 2-phase at all, at last not yet.

**We no longer support using the MIR borrow checker without NLL.** It is going to be increasingly untenable to support lexical mode as we go forward, I think, and also of increasingly little value. This also exposed a few bugs in NLL mode due to increased testing.

r? @pnkfelix
cc @bobtwinkles
-rw-r--r--src/librustc/infer/error_reporting/mod.rs8
-rw-r--r--src/librustc/mir/mod.rs2
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc/ty/context.rs14
-rw-r--r--src/librustc_mir/borrow_check/borrow_set.rs328
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs57
-rw-r--r--src/librustc_mir/borrow_check/flows.rs23
-rw-r--r--src/librustc_mir/borrow_check/mod.rs271
-rw-r--r--src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs119
-rw-r--r--src/librustc_mir/borrow_check/nll/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/place_ext.rs60
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs609
-rw-r--r--src/librustc_mir/dataflow/impls/mod.rs2
-rw-r--r--src/librustc_mir/dataflow/mod.rs3
-rw-r--r--src/librustc_mir/dataflow/move_paths/mod.rs3
-rw-r--r--src/librustc_mir/lib.rs1
-rw-r--r--src/test/compile-fail/E0501.rs6
-rw-r--r--src/test/compile-fail/borrowck/borrowck-asm.rs2
-rw-r--r--src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs10
-rw-r--r--src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs64
-rw-r--r--src/test/compile-fail/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs8
-rw-r--r--src/test/compile-fail/borrowck/borrowck-lend-flow-match.rs5
-rw-r--r--src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs4
-rw-r--r--src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs8
-rw-r--r--src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs1
-rw-r--r--src/test/compile-fail/borrowck/borrowck-pat-reassign-binding.rs3
-rw-r--r--src/test/compile-fail/borrowck/borrowck-union-borrow.rs16
-rw-r--r--src/test/compile-fail/borrowck/two-phase-across-loop.rs34
-rw-r--r--src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs5
-rw-r--r--src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs11
-rw-r--r--src/test/compile-fail/borrowck/two-phase-cannot-nest-mut-self-calls.rs7
-rw-r--r--src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs62
-rw-r--r--src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs7
-rw-r--r--src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference.rs13
-rw-r--r--src/test/compile-fail/borrowck/two-phase-sneaky.rs7
-rw-r--r--src/test/compile-fail/coerce-overloaded-autoderef.rs2
-rw-r--r--src/test/compile-fail/hrtb-identity-fn-borrows.rs1
-rw-r--r--src/test/compile-fail/issue-36082.rs7
-rw-r--r--src/test/compile-fail/mir_check_cast_closure.rs4
-rw-r--r--src/test/compile-fail/mir_check_cast_reify.rs4
-rw-r--r--src/test/compile-fail/mir_check_cast_unsafe_fn.rs4
-rw-r--r--src/test/compile-fail/mir_check_cast_unsize.rs4
-rw-r--r--src/test/compile-fail/mut-pattern-internal-mutability.rs3
-rw-r--r--src/test/compile-fail/nll/loan_ends_mid_block_pair.rs2
-rw-r--r--src/test/compile-fail/nll/loan_ends_mid_block_vec.rs2
-rw-r--r--src/test/compile-fail/nll/reference-carried-through-struct-field.rs2
-rw-r--r--src/test/compile-fail/nll/region-ends-after-if-condition.rs2
-rw-r--r--src/test/compile-fail/nll/return_from_loop.rs2
-rw-r--r--src/test/compile-fail/nll/where_clauses_in_functions.rs4
-rw-r--r--src/test/compile-fail/nll/where_clauses_in_structs.rs4
-rw-r--r--src/test/compile-fail/regions-pattern-typing-issue-19997.rs3
-rw-r--r--src/test/compile-fail/regions-static-bound.rs8
-rw-r--r--src/test/mir-opt/nll/liveness-call-subtlety.rs2
-rw-r--r--src/test/mir-opt/nll/liveness-drop-intra-block.rs2
-rw-r--r--src/test/mir-opt/nll/liveness-interblock.rs2
-rw-r--r--src/test/mir-opt/nll/named-lifetimes-basic.rs4
-rw-r--r--src/test/mir-opt/nll/reborrow-basic.rs4
-rw-r--r--src/test/mir-opt/nll/region-liveness-basic.rs4
-rw-r--r--src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs4
-rw-r--r--src/test/mir-opt/nll/region-subtyping-basic.rs4
-rw-r--r--src/test/run-pass/borrowck/two-phase-baseline.rs4
-rw-r--r--src/test/run-pass/impl-trait/example-calendar.rs2
-rw-r--r--src/test/ui/borrowck/borrowck-closures-two-mut.rs5
-rw-r--r--src/test/ui/borrowck/borrowck-closures-two-mut.stderr42
-rw-r--r--src/test/ui/borrowck/two-phase-method-receivers.rs4
-rw-r--r--src/test/ui/borrowck/two-phase-multiple-activations.rs4
-rw-r--r--src/test/ui/issue-45697-1.rs1
-rw-r--r--src/test/ui/issue-45697-1.stderr16
-rw-r--r--src/test/ui/issue-45697.rs1
-rw-r--r--src/test/ui/issue-45697.stderr16
-rw-r--r--src/test/ui/issue-46471-1.stderr17
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-nested.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-ref.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr8
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-val.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs4
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr4
-rw-r--r--src/test/ui/nll/constant.rs2
-rw-r--r--src/test/ui/nll/drop-may-dangle.rs2
-rw-r--r--src/test/ui/nll/drop-no-may-dangle.rs2
-rw-r--r--src/test/ui/nll/get_default.rs2
-rw-r--r--src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs2
-rw-r--r--src/test/ui/nll/maybe-initialized-drop-uninitialized.rs2
-rw-r--r--src/test/ui/nll/maybe-initialized-drop-with-fragment.rs2
-rw-r--r--src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs2
-rw-r--r--src/test/ui/nll/maybe-initialized-drop.rs2
-rw-r--r--src/test/ui/nll/projection-return.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/impl-trait-captures.rs4
-rw-r--r--src/test/ui/nll/ty-outlives/impl-trait-captures.stderr2
-rw-r--r--src/test/ui/nll/ty-outlives/impl-trait-outlives.rs6
-rw-r--r--src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/projection-implied-bounds.rs4
-rw-r--r--src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr2
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs6
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs6
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.rs8
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr6
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs8
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr6
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs10
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr8
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr6
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs6
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs6
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr12
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn-body.rs4
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr2
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn.rs6
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-fn.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs2
-rw-r--r--src/tools/compiletest/src/runtest.rs2
145 files changed, 1141 insertions, 1128 deletions
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 8d314e25197..d8a2c95ab59 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -303,7 +303,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     ) {
         debug!("report_region_errors(): {} errors to start", errors.len());
 
-        if will_later_be_reported_by_nll && self.tcx.nll() {
+        if will_later_be_reported_by_nll && self.tcx.use_mir_borrowck() {
             // With `#![feature(nll)]`, we want to present a nice user
             // experience, so don't even mention the errors from the
             // AST checker.
@@ -311,20 +311,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 return;
             }
 
-            // But with -Znll, it's nice to have some note for later.
+            // But with nll, it's nice to have some note for later.
             for error in errors {
                 match *error {
                     RegionResolutionError::ConcreteFailure(ref origin, ..)
                     | RegionResolutionError::GenericBoundFailure(ref origin, ..) => {
                         self.tcx
                             .sess
-                            .span_warn(origin.span(), "not reporting region error due to -Znll");
+                            .span_warn(origin.span(), "not reporting region error due to nll");
                     }
 
                     RegionResolutionError::SubSupConflict(ref rvo, ..) => {
                         self.tcx
                             .sess
-                            .span_warn(rvo.span(), "not reporting region error due to -Znll");
+                            .span_warn(rvo.span(), "not reporting region error due to nll");
                     }
                 }
             }
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 33f52ab09c8..c525c4ed651 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1991,7 +1991,7 @@ impl Location {
         Location { block: self.block, statement_index: self.statement_index + 1 }
     }
 
-    pub fn dominates(&self, other: &Location, dominators: &Dominators<BasicBlock>) -> bool {
+    pub fn dominates(&self, other: Location, dominators: &Dominators<BasicBlock>) -> bool {
         if self.block == other.block {
             self.statement_index <= other.statement_index
         } else {
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 0f7de0ffffe..59823390a0a 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1259,8 +1259,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         useful for profiling / PGO."),
     relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
         "choose which RELRO level to use"),
-    nll: bool = (false, parse_bool, [UNTRACKED],
-                 "run the non-lexical lifetimes MIR pass"),
     disable_nll_user_type_assert: bool = (false, parse_bool, [UNTRACKED],
         "disable user provided type assertion in NLL"),
     trans_time_graph: bool = (false, parse_bool, [UNTRACKED],
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 4c7d8d7f44e..28ad5edbd2d 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1459,15 +1459,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self.on_disk_query_result_cache.serialize(self.global_tcx(), encoder)
     }
 
-    /// If true, we should use NLL-style region checking instead of
-    /// lexical style.
-    pub fn nll(self) -> bool {
-        self.features().nll || self.sess.opts.debugging_opts.nll
-    }
-
     /// If true, we should use the MIR-based borrowck (we may *also* use
     /// the AST-based borrowck).
-    pub fn use_mir(self) -> bool {
+    pub fn use_mir_borrowck(self) -> bool {
         self.borrowck_mode().use_mir()
     }
 
@@ -1486,7 +1480,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             mode @ BorrowckMode::Compare => mode,
 
             mode @ BorrowckMode::Ast => {
-                if self.nll() {
+                if self.features().nll {
                     BorrowckMode::Mir
                 } else {
                     mode
@@ -1500,11 +1494,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     /// MIR borrowck, but not when NLL is used. They are also consumed
     /// by the validation stuff.
     pub fn emit_end_regions(self) -> bool {
-        // FIXME(#46875) -- we should not emit end regions when NLL is enabled,
-        // but for now we can't stop doing so because it causes false positives
         self.sess.opts.debugging_opts.emit_end_regions ||
             self.sess.opts.debugging_opts.mir_emit_validate > 0 ||
-            self.use_mir()
+            self.use_mir_borrowck()
     }
 
     #[inline]
diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs
new file mode 100644
index 00000000000..ccfb44a8b58
--- /dev/null
+++ b/src/librustc_mir/borrow_check/borrow_set.rs
@@ -0,0 +1,328 @@
+// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use borrow_check::place_ext::PlaceExt;
+use dataflow::indexes::BorrowIndex;
+use rustc::mir::traversal;
+use rustc::mir::visit::{PlaceContext, Visitor};
+use rustc::mir::{self, Location, Mir, Place};
+use rustc::ty::{Region, TyCtxt};
+use rustc::util::nodemap::{FxHashMap, FxHashSet};
+use rustc_data_structures::indexed_vec::IndexVec;
+use std::fmt;
+use std::hash::Hash;
+use std::ops::Index;
+
+crate struct BorrowSet<'tcx> {
+    /// The fundamental map relating bitvector indexes to the borrows
+    /// in the MIR.
+    crate borrows: IndexVec<BorrowIndex, BorrowData<'tcx>>,
+
+    /// Each borrow is also uniquely identified in the MIR by the
+    /// `Location` of the assignment statement in which it appears on
+    /// the right hand side; we map each such location to the
+    /// corresponding `BorrowIndex`.
+    crate location_map: FxHashMap<Location, BorrowIndex>,
+
+    /// Locations which activate borrows.
+    /// NOTE: A given location may activate more than one borrow in the future
+    /// when more general two-phase borrow support is introduced, but for now we
+    /// only need to store one borrow index
+    crate activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
+
+    /// Every borrow has a region; this maps each such regions back to
+    /// its borrow-indexes.
+    crate region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
+
+    /// Map from local to all the borrows on that local
+    crate local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
+}
+
+impl<'tcx> Index<BorrowIndex> for BorrowSet<'tcx> {
+    type Output = BorrowData<'tcx>;
+
+    fn index(&self, index: BorrowIndex) -> &BorrowData<'tcx> {
+        &self.borrows[index]
+    }
+}
+
+#[derive(Debug)]
+crate struct BorrowData<'tcx> {
+    /// Location where the borrow reservation starts.
+    /// In many cases, this will be equal to the activation location but not always.
+    crate reserve_location: Location,
+    /// Location where the borrow is activated. None if this is not a
+    /// 2-phase borrow.
+    crate activation_location: Option<Location>,
+    /// What kind of borrow this is
+    crate kind: mir::BorrowKind,
+    /// The region for which this borrow is live
+    crate region: Region<'tcx>,
+    /// Place from which we are borrowing
+    crate borrowed_place: mir::Place<'tcx>,
+    /// Place to which the borrow was stored
+    crate assigned_place: mir::Place<'tcx>,
+}
+
+impl<'tcx> fmt::Display for BorrowData<'tcx> {
+    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
+        let kind = match self.kind {
+            mir::BorrowKind::Shared => "",
+            mir::BorrowKind::Unique => "uniq ",
+            mir::BorrowKind::Mut { .. } => "mut ",
+        };
+        let region = format!("{}", self.region);
+        let region = if region.len() > 0 {
+            format!("{} ", region)
+        } else {
+            region
+        };
+        write!(w, "&{}{}{:?}", region, kind, self.borrowed_place)
+    }
+}
+
+impl<'tcx> BorrowSet<'tcx> {
+    pub fn build(tcx: TyCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>) -> Self {
+        let mut visitor = GatherBorrows {
+            tcx,
+            mir,
+            idx_vec: IndexVec::new(),
+            location_map: FxHashMap(),
+            activation_map: FxHashMap(),
+            region_map: FxHashMap(),
+            local_map: FxHashMap(),
+            pending_activations: FxHashMap(),
+        };
+
+        for (block, block_data) in traversal::preorder(mir) {
+            visitor.visit_basic_block_data(block, block_data);
+        }
+
+        // Double check: We should have found an activation for every pending
+        // activation.
+        assert_eq!(
+            visitor
+                .pending_activations
+                .iter()
+                .find(|&(_local, &borrow_index)| visitor.idx_vec[borrow_index]
+                    .activation_location
+                    .is_none()),
+            None,
+            "never found an activation for this borrow!",
+        );
+
+        BorrowSet {
+            borrows: visitor.idx_vec,
+            location_map: visitor.location_map,
+            activation_map: visitor.activation_map,
+            region_map: visitor.region_map,
+            local_map: visitor.local_map,
+        }
+    }
+
+    crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] {
+        self.activation_map
+            .get(&location)
+            .map(|activations| &activations[..])
+            .unwrap_or(&[])
+    }
+}
+
+struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    mir: &'a Mir<'tcx>,
+    idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>,
+    location_map: FxHashMap<Location, BorrowIndex>,
+    activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
+    region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
+    local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
+
+    /// When we encounter a 2-phase borrow statement, it will always
+    /// be assigning into a temporary TEMP:
+    ///
+    ///    TEMP = &foo
+    ///
+    /// We add TEMP into this map with `b`, where `b` is the index of
+    /// the borrow. When we find a later use of this activation, we
+    /// remove from the map (and add to the "tombstone" set below).
+    pending_activations: FxHashMap<mir::Local, BorrowIndex>,
+}
+
+impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
+    fn visit_assign(
+        &mut self,
+        block: mir::BasicBlock,
+        assigned_place: &mir::Place<'tcx>,
+        rvalue: &mir::Rvalue<'tcx>,
+        location: mir::Location,
+    ) {
+        if let mir::Rvalue::Ref(region, kind, ref borrowed_place) = *rvalue {
+            if borrowed_place.is_unsafe_place(self.tcx, self.mir) {
+                return;
+            }
+
+            let borrow = BorrowData {
+                kind,
+                region,
+                reserve_location: location,
+                activation_location: None,
+                borrowed_place: borrowed_place.clone(),
+                assigned_place: assigned_place.clone(),
+            };
+            let idx = self.idx_vec.push(borrow);
+            self.location_map.insert(location, idx);
+
+            self.insert_as_pending_if_two_phase(location, &assigned_place, region, kind, idx);
+
+            insert(&mut self.region_map, &region, idx);
+            if let Some(local) = borrowed_place.root_local() {
+                insert(&mut self.local_map, &local, idx);
+            }
+        }
+
+        return self.super_assign(block, assigned_place, rvalue, location);
+
+        fn insert<'a, K, V>(map: &'a mut FxHashMap<K, FxHashSet<V>>, k: &K, v: V)
+        where
+            K: Clone + Eq + Hash,
+            V: Eq + Hash,
+        {
+            map.entry(k.clone()).or_insert(FxHashSet()).insert(v);
+        }
+    }
+
+    fn visit_place(
+        &mut self,
+        place: &mir::Place<'tcx>,
+        context: PlaceContext<'tcx>,
+        location: Location,
+    ) {
+        self.super_place(place, context, location);
+
+        // We found a use of some temporary TEMP...
+        if let Place::Local(temp) = place {
+            // ... check whether we (earlier) saw a 2-phase borrow like
+            //
+            //     TMP = &mut place
+            match self.pending_activations.get(temp) {
+                Some(&borrow_index) => {
+                    let borrow_data = &mut self.idx_vec[borrow_index];
+
+                    // Watch out: the use of TMP in the borrow
+                    // itself doesn't count as an
+                    // activation. =)
+                    if borrow_data.reserve_location == location && context == PlaceContext::Store {
+                        return;
+                    }
+
+                    if let Some(other_activation) = borrow_data.activation_location {
+                        span_bug!(
+                            self.mir.source_info(location).span,
+                            "found two activations for 2-phase borrow temporary {:?}: \
+                             {:?} and {:?}",
+                            temp,
+                            location,
+                            other_activation,
+                        );
+                    }
+
+                    // Otherwise, this is the unique later use
+                    // that we expect.
+                    borrow_data.activation_location = Some(location);
+                    self.activation_map
+                        .entry(location)
+                        .or_insert(Vec::new())
+                        .push(borrow_index);
+                }
+
+                None => {}
+            }
+        }
+    }
+
+    fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: mir::Location) {
+        if let mir::Rvalue::Ref(region, kind, ref place) = *rvalue {
+            // double-check that we already registered a BorrowData for this
+
+            let borrow_index = self.location_map[&location];
+            let borrow_data = &self.idx_vec[borrow_index];
+            assert_eq!(borrow_data.reserve_location, location);
+            assert_eq!(borrow_data.kind, kind);
+            assert_eq!(borrow_data.region, region);
+            assert_eq!(borrow_data.borrowed_place, *place);
+        }
+
+        return self.super_rvalue(rvalue, location);
+    }
+
+    fn visit_statement(
+        &mut self,
+        block: mir::BasicBlock,
+        statement: &mir::Statement<'tcx>,
+        location: Location,
+    ) {
+        return self.super_statement(block, statement, location);
+    }
+}
+
+impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
+    /// Returns true if the borrow represented by `kind` is
+    /// allowed to be split into separate Reservation and
+    /// Activation phases.
+    fn allow_two_phase_borrow(&self, kind: mir::BorrowKind) -> bool {
+        self.tcx.two_phase_borrows()
+            && (kind.allows_two_phase_borrow()
+                || self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref)
+    }
+
+    /// If this is a two-phase borrow, then we will record it
+    /// as "pending" until we find the activating use.
+    fn insert_as_pending_if_two_phase(
+        &mut self,
+        start_location: Location,
+        assigned_place: &mir::Place<'tcx>,
+        region: Region<'tcx>,
+        kind: mir::BorrowKind,
+        borrow_index: BorrowIndex,
+    ) {
+        debug!(
+            "Borrows::insert_as_pending_if_two_phase({:?}, {:?}, {:?}, {:?})",
+            start_location, assigned_place, region, borrow_index,
+        );
+
+        if !self.allow_two_phase_borrow(kind) {
+            debug!("  -> {:?}", start_location);
+            return;
+        }
+
+        // When we encounter a 2-phase borrow statement, it will always
+        // be assigning into a temporary TEMP:
+        //
+        //    TEMP = &foo
+        //
+        // so extract `temp`.
+        let temp = if let &mir::Place::Local(temp) = assigned_place {
+            temp
+        } else {
+            span_bug!(
+                self.mir.source_info(start_location).span,
+                "expected 2-phase borrow to assign to a local, not `{:?}`",
+                assigned_place,
+            );
+        };
+
+        // Insert `temp` into the list of pending activations. From
+        // now on, we'll be on the lookout for a use of it. Note that
+        // we are guaranteed that this use will come after the
+        // assignment.
+        let old_value = self.pending_activations.insert(temp, borrow_index);
+        assert!(old_value.is_none());
+    }
+}
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index aaed1dd871b..3dc5a7a8490 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -18,7 +18,9 @@ use rustc_data_structures::sync::Lrc;
 
 use super::{Context, MirBorrowckCtxt};
 use super::{InitializationRequiringAction, PrefixSet};
-use dataflow::{Borrows, BorrowData, FlowAtLocation, MovingOutStatements};
+use super::borrow_set::BorrowData;
+
+use dataflow::{FlowAtLocation, MovingOutStatements};
 use dataflow::move_paths::MovePathIndex;
 use util::borrowck_errors::{BorrowckErrors, Origin};
 
@@ -261,7 +263,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         (place, span): (&Place<'tcx>, Span),
         gen_borrow_kind: BorrowKind,
         issued_borrow: &BorrowData<'tcx>,
-        end_issued_loan_span: Option<Span>,
     ) {
         let issued_span = self.retrieve_borrow_span(issued_borrow);
 
@@ -295,7 +296,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     "it",
                     rgt,
                     "",
-                    end_issued_loan_span,
+                    None,
                     Origin::Mir,
                 )
             }
@@ -307,7 +308,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     "",
                     issued_span,
                     "",
-                    end_issued_loan_span,
+                    None,
                     Origin::Mir,
                 )
             }
@@ -317,7 +318,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     span,
                     &desc_place,
                     issued_span,
-                    end_issued_loan_span,
+                    None,
                     Origin::Mir,
                 )
             }
@@ -329,7 +330,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 issued_span,
                 "it",
                 "",
-                end_issued_loan_span,
+                None,
                 Origin::Mir,
             ),
 
@@ -341,7 +342,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     lft,
                     issued_span,
                     "",
-                    end_issued_loan_span,
+                    None,
                     Origin::Mir,
                 )
             }
@@ -354,7 +355,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     lft,
                     issued_span,
                     "",
-                    end_issued_loan_span,
+                    None,
                     Origin::Mir,
                 )
             }
@@ -389,10 +390,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         context: Context,
         borrow: &BorrowData<'tcx>,
         drop_span: Span,
-        borrows: &Borrows<'cx, 'gcx, 'tcx>
     ) {
-        let end_span = borrows.opt_region_end_span(&borrow.region);
-        let scope_tree = borrows.scope_tree();
+        let scope_tree = self.tcx.region_scope_tree(self.mir_def_id);
         let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All)
             .last()
             .unwrap();
@@ -426,7 +425,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     drop_span,
                     borrow_span,
                     proper_span,
-                    end_span,
                 );
             }
             (RegionKind::ReScope(_), None) => {
@@ -437,7 +435,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     drop_span,
                     borrow_span,
                     proper_span,
-                    end_span,
                 );
             }
             (RegionKind::ReEarlyBound(_), Some(name))
@@ -453,7 +450,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     drop_span,
                     borrow_span,
                     proper_span,
-                    end_span,
                 );
             }
             (RegionKind::ReEarlyBound(_), None)
@@ -468,7 +464,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     drop_span,
                     borrow_span,
                     proper_span,
-                    end_span,
                 );
             }
             (RegionKind::ReLateBound(_, _), _)
@@ -490,7 +485,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         drop_span: Span,
         borrow_span: Span,
         _proper_span: Span,
-        end_span: Option<Span>,
     ) {
         let tcx = self.tcx;
         let mut err =
@@ -500,9 +494,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             drop_span,
             format!("`{}` dropped here while still borrowed", name),
         );
-        if let Some(end) = end_span {
-            err.span_label(end, "borrowed value needs to live until here");
-        }
         self.explain_why_borrow_contains_point(context, borrow, &mut err);
         err.emit();
     }
@@ -515,7 +506,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         drop_span: Span,
         _borrow_span: Span,
         proper_span: Span,
-        end_span: Option<Span>,
     ) {
         let tcx = self.tcx;
         let mut err =
@@ -526,9 +516,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             "temporary value dropped here while still borrowed",
         );
         err.note("consider using a `let` binding to increase its lifetime");
-        if let Some(end) = end_span {
-            err.span_label(end, "temporary value needs to live until here");
-        }
         self.explain_why_borrow_contains_point(context, borrow, &mut err);
         err.emit();
     }
@@ -542,7 +529,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         drop_span: Span,
         borrow_span: Span,
         _proper_span: Span,
-        _end_span: Option<Span>,
     ) {
         debug!(
             "report_unscoped_local_value_does_not_live_long_enough(\
@@ -557,16 +543,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         err.span_label(borrow_span, "borrowed value does not live long enough");
         err.span_label(drop_span, "borrowed value only lives until here");
 
-        if !tcx.nll() {
-            tcx.note_and_explain_region(
-                scope_tree,
-                &mut err,
-                "borrowed value must be valid for ",
-                borrow.region,
-                "...",
-            );
-        }
-
         self.explain_why_borrow_contains_point(context, borrow, &mut err);
         err.emit();
     }
@@ -579,7 +555,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         drop_span: Span,
         _borrow_span: Span,
         proper_span: Span,
-        _end_span: Option<Span>,
     ) {
         debug!(
             "report_unscoped_temporary_value_does_not_live_long_enough(\
@@ -594,16 +569,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         err.span_label(proper_span, "temporary value does not live long enough");
         err.span_label(drop_span, "temporary value only lives until here");
 
-        if !tcx.nll() {
-            tcx.note_and_explain_region(
-                scope_tree,
-                &mut err,
-                "borrowed value must be valid for ",
-                borrow.region,
-                "...",
-            );
-        }
-
         self.explain_why_borrow_contains_point(context, borrow, &mut err);
         err.emit();
     }
@@ -834,7 +799,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     }
 
     // Retrieve span of given borrow from the current MIR representation
-    pub fn retrieve_borrow_span(&self, borrow: &BorrowData) -> Span {
+    crate fn retrieve_borrow_span(&self, borrow: &BorrowData) -> Span {
         self.mir.source_info(borrow.reserve_location).span
     }
 
diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs
index ceff380c594..070dc1d09bf 100644
--- a/src/librustc_mir/borrow_check/flows.rs
+++ b/src/librustc_mir/borrow_check/flows.rs
@@ -14,17 +14,19 @@
 //! but is not as ugly as it is right now.
 
 use rustc::mir::{BasicBlock, Location};
+use rustc_data_structures::indexed_set::Iter;
 
 use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
 use dataflow::{EverInitializedPlaces, MovingOutStatements};
 use dataflow::{Borrows};
 use dataflow::{FlowAtLocation, FlowsAtLocation};
 use dataflow::move_paths::HasMoveData;
+use dataflow::move_paths::indexes::BorrowIndex;
 use std::fmt;
 
 // (forced to be `pub` due to its use as an associated type below.)
-pub(crate) struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> {
-    pub borrows: FlowAtLocation<Borrows<'b, 'gcx, 'tcx>>,
+crate struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> {
+    borrows: FlowAtLocation<Borrows<'b, 'gcx, 'tcx>>,
     pub inits: FlowAtLocation<MaybeInitializedPlaces<'b, 'gcx, 'tcx>>,
     pub uninits: FlowAtLocation<MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>,
     pub move_outs: FlowAtLocation<MovingOutStatements<'b, 'gcx, 'tcx>>,
@@ -32,7 +34,7 @@ pub(crate) struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> {
 }
 
 impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> {
-    pub fn new(
+    crate fn new(
         borrows: FlowAtLocation<Borrows<'b, 'gcx, 'tcx>>,
         inits: FlowAtLocation<MaybeInitializedPlaces<'b, 'gcx, 'tcx>>,
         uninits: FlowAtLocation<MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>,
@@ -47,6 +49,14 @@ impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> {
             ever_inits,
         }
     }
+
+    crate fn borrows_in_scope(&self) -> impl Iterator<Item = BorrowIndex> + '_ {
+        self.borrows.iter_incoming()
+    }
+
+    crate fn with_outgoing_borrows(&self, op: impl FnOnce(Iter<BorrowIndex>)) {
+        self.borrows.with_iter_outgoing(op)
+    }
 }
 
 macro_rules! each_flow {
@@ -88,9 +98,8 @@ impl<'b, 'gcx, 'tcx> fmt::Display for Flows<'b, 'gcx, 'tcx> {
                 s.push_str(", ");
             };
             saw_one = true;
-            let borrow_data = &self.borrows.operator().borrows()[borrow.borrow_index()];
-            s.push_str(&format!("{}{}", borrow_data,
-                                if borrow.is_activation() { "@active" } else { "" }));
+            let borrow_data = &self.borrows.operator().borrows()[borrow];
+            s.push_str(&format!("{}", borrow_data));
         });
         s.push_str("] ");
 
@@ -101,7 +110,7 @@ impl<'b, 'gcx, 'tcx> fmt::Display for Flows<'b, 'gcx, 'tcx> {
                 s.push_str(", ");
             };
             saw_one = true;
-            let borrow_data = &self.borrows.operator().borrows()[borrow.borrow_index()];
+            let borrow_data = &self.borrows.operator().borrows()[borrow];
             s.push_str(&format!("{}", borrow_data));
         });
         s.push_str("] ");
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 87379651c23..4dd8d245d3b 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -22,13 +22,13 @@ use rustc::mir::{Mir, Mutability, Operand, Projection, ProjectionElem, Rvalue};
 use rustc::mir::{Field, Statement, StatementKind, Terminator, TerminatorKind};
 use rustc::mir::ClosureRegionRequirements;
 
+use rustc_data_structures::control_flow_graph::dominators::Dominators;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::indexed_set::IdxSetBuf;
 use rustc_data_structures::indexed_vec::Idx;
 
 use std::rc::Rc;
 
-use syntax::ast;
 use syntax_pos::Span;
 
 use dataflow::{do_dataflow, DebugFormatted};
@@ -37,7 +37,7 @@ use dataflow::MoveDataParamEnv;
 use dataflow::{DataflowResultsConsumer};
 use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
 use dataflow::{EverInitializedPlaces, MovingOutStatements};
-use dataflow::{BorrowData, Borrows, ReserveOrActivateIndex};
+use dataflow::Borrows;
 use dataflow::indexes::BorrowIndex;
 use dataflow::move_paths::{IllegalMoveOriginKind, MoveError};
 use dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex};
@@ -46,12 +46,15 @@ use util::collect_writes::FindAssignments;
 
 use std::iter;
 
+use self::borrow_set::{BorrowSet, BorrowData};
 use self::flows::Flows;
 use self::prefixes::PrefixSet;
 use self::MutateMode::{JustWrite, WriteAndRead};
 
+crate mod borrow_set;
 mod error_reporting;
 mod flows;
+crate mod place_ext;
 mod prefixes;
 
 pub(crate) mod nll;
@@ -70,7 +73,7 @@ fn mir_borrowck<'a, 'tcx>(
     let input_mir = tcx.mir_validated(def_id);
     debug!("run query mir_borrowck: {}", tcx.item_path_str(def_id));
 
-    if !tcx.has_attr(def_id, "rustc_mir_borrowck") && !tcx.use_mir() {
+    if !tcx.has_attr(def_id, "rustc_mir_borrowck") && !tcx.use_mir_borrowck() {
         return None;
     }
 
@@ -95,19 +98,13 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         .as_local_node_id(def_id)
         .expect("do_mir_borrowck: non-local DefId");
 
-    // Make our own copy of the MIR. This copy will be modified (in place) to
-    // contain non-lexical lifetimes. It will have a lifetime tied
-    // to the inference context.
+    // Replace all regions with fresh inference variables. This
+    // requires first making our own copy of the MIR. This copy will
+    // be modified (in place) to contain non-lexical lifetimes. It
+    // will have a lifetime tied to the inference context.
     let mut mir: Mir<'tcx> = input_mir.clone();
-    let free_regions = if !tcx.nll() {
-        None
-    } else {
-        let mir = &mut mir;
-
-        // Replace all regions with fresh inference variables.
-        Some(nll::replace_regions_in_mir(infcx, def_id, param_env, mir))
-    };
-    let mir = &mir;
+    let free_regions = nll::replace_regions_in_mir(infcx, def_id, param_env, &mut mir);
+    let mir = &mir; // no further changes
 
     let move_data: MoveData<'tcx> = match MoveData::gather_moves(mir, tcx) {
         Ok(move_data) => move_data,
@@ -189,22 +186,20 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         |bd, i| DebugFormatted::new(&bd.move_data().inits[i]),
     ));
 
+    let borrow_set = Rc::new(BorrowSet::build(tcx, mir));
+
     // If we are in non-lexical mode, compute the non-lexical lifetimes.
-    let (opt_regioncx, opt_closure_req) = if let Some(free_regions) = free_regions {
-        let (regioncx, opt_closure_req) = nll::compute_regions(
-            infcx,
-            def_id,
-            free_regions,
-            mir,
-            param_env,
-            &mut flow_inits,
-            &mdpe.move_data,
-        );
-        (Some(Rc::new(regioncx)), opt_closure_req)
-    } else {
-        assert!(!tcx.nll());
-        (None, None)
-    };
+    let (regioncx, opt_closure_req) = nll::compute_regions(
+        infcx,
+        def_id,
+        free_regions,
+        mir,
+        param_env,
+        &mut flow_inits,
+        &mdpe.move_data,
+        &borrow_set,
+    );
+    let regioncx = Rc::new(regioncx);
     let flow_inits = flow_inits; // remove mut
 
     let flow_borrows = FlowAtLocation::new(do_dataflow(
@@ -213,24 +208,24 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         id,
         &attributes,
         &dead_unwinds,
-        Borrows::new(tcx, mir, opt_regioncx.clone(), def_id, body_id),
-        |rs, i| {
-            DebugFormatted::new(&(i.kind(), rs.location(i.borrow_index())))
-        }
+        Borrows::new(tcx, mir, regioncx.clone(), def_id, body_id, &borrow_set),
+        |rs, i| DebugFormatted::new(&rs.location(i)),
     ));
 
-    let movable_generator = !match tcx.hir.get(id) {
+    let movable_generator = match tcx.hir.get(id) {
         hir::map::Node::NodeExpr(&hir::Expr {
             node: hir::ExprClosure(.., Some(hir::GeneratorMovability::Static)),
             ..
-        }) => true,
-        _ => false,
+        }) => false,
+        _ => true,
     };
 
+    let dominators = mir.dominators();
+
     let mut mbcx = MirBorrowckCtxt {
         tcx: tcx,
         mir: mir,
-        node_id: id,
+        mir_def_id: def_id,
         move_data: &mdpe.move_data,
         param_env: param_env,
         movable_generator,
@@ -241,8 +236,10 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         access_place_error_reported: FxHashSet(),
         reservation_error_reported: FxHashSet(),
         moved_error_reported: FxHashSet(),
-        nonlexical_regioncx: opt_regioncx,
+        nonlexical_regioncx: regioncx,
         nonlexical_cause_info: None,
+        borrow_set,
+        dominators,
     };
 
     let mut state = Flows::new(
@@ -262,7 +259,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
 pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
     tcx: TyCtxt<'cx, 'gcx, 'tcx>,
     mir: &'cx Mir<'tcx>,
-    node_id: ast::NodeId,
+    mir_def_id: DefId,
     move_data: &'cx MoveData<'tcx>,
     param_env: ParamEnv<'gcx>,
     movable_generator: bool,
@@ -293,8 +290,14 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
     /// Non-lexical region inference context, if NLL is enabled.  This
     /// contains the results from region inference and lets us e.g.
     /// find out which CFG points are contained in each borrow region.
-    nonlexical_regioncx: Option<Rc<RegionInferenceContext<'tcx>>>,
+    nonlexical_regioncx: Rc<RegionInferenceContext<'tcx>>,
     nonlexical_cause_info: Option<RegionCausalInfo>,
+
+    /// The set of borrows extracted from the MIR
+    borrow_set: Rc<BorrowSet<'tcx>>,
+
+    /// Dominators for MIR
+    dominators: Dominators<BasicBlock>,
 }
 
 // Check that:
@@ -535,11 +538,10 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
 
                 if self.movable_generator {
                     // Look for any active borrows to locals
-                    let domain = flow_state.borrows.operator();
-                    let data = domain.borrows();
-                    flow_state.borrows.with_iter_outgoing(|borrows| {
+                    let borrow_set = self.borrow_set.clone();
+                    flow_state.with_outgoing_borrows(|borrows| {
                         for i in borrows {
-                            let borrow = &data[i.borrow_index()];
+                            let borrow = &borrow_set[i];
                             self.check_for_local_borrow(borrow, span);
                         }
                     });
@@ -551,13 +553,12 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
                 // Often, the storage will already have been killed by an explicit
                 // StorageDead, but we don't always emit those (notably on unwind paths),
                 // so this "extra check" serves as a kind of backup.
-                let domain = flow_state.borrows.operator();
-                let data = domain.borrows();
-                flow_state.borrows.with_iter_outgoing(|borrows| {
+                let borrow_set = self.borrow_set.clone();
+                flow_state.with_outgoing_borrows(|borrows| {
                     for i in borrows {
-                        let borrow = &data[i.borrow_index()];
+                        let borrow = &borrow_set[i];
                         let context = ContextKind::StorageDead.new(loc);
-                        self.check_for_invalidation_at_exit(context, borrow, span, flow_state);
+                        self.check_for_invalidation_at_exit(context, borrow, span);
                     }
                 });
             }
@@ -836,27 +837,34 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         rw: ReadOrWrite,
         flow_state: &Flows<'cx, 'gcx, 'tcx>,
     ) -> bool {
+        debug!(
+            "check_access_for_conflict(context={:?}, place_span={:?}, sd={:?}, rw={:?})",
+            context,
+            place_span,
+            sd,
+            rw,
+        );
+
         let mut error_reported = false;
         self.each_borrow_involving_path(
             context,
             (sd, place_span.0),
             flow_state,
-            |this, index, borrow| match (rw, borrow.kind) {
+            |this, borrow_index, borrow| match (rw, borrow.kind) {
                 // Obviously an activation is compatible with its own
                 // reservation (or even prior activating uses of same
                 // borrow); so don't check if they interfere.
                 //
                 // NOTE: *reservations* do conflict with themselves;
                 // thus aren't injecting unsoundenss w/ this check.)
-                (Activation(_, activating), _) if activating == index.borrow_index() => {
+                (Activation(_, activating), _) if activating == borrow_index => {
                     debug!(
                         "check_access_for_conflict place_span: {:?} sd: {:?} rw: {:?} \
-                         skipping {:?} b/c activation of same borrow_index: {:?}",
+                         skipping {:?} b/c activation of same borrow_index",
                         place_span,
                         sd,
                         rw,
-                        (index, borrow),
-                        index.borrow_index()
+                        (borrow_index, borrow),
                     );
                     Control::Continue
                 }
@@ -867,7 +875,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
 
                 (Read(kind), BorrowKind::Unique) | (Read(kind), BorrowKind::Mut { .. }) => {
                     // Reading from mere reservations of mutable-borrows is OK.
-                    if this.allow_two_phase_borrow(borrow.kind) && index.is_reservation() {
+                    if !this.is_active(borrow, context.loc) {
+                        assert!(this.allow_two_phase_borrow(borrow.kind));
                         return Control::Continue;
                     }
 
@@ -877,17 +886,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                             this.report_use_while_mutably_borrowed(context, place_span, borrow)
                         }
                         ReadKind::Borrow(bk) => {
-                            let end_issued_loan_span = flow_state
-                                .borrows
-                                .operator()
-                                .opt_region_end_span(&borrow.region);
                             error_reported = true;
                             this.report_conflicting_borrow(
                                 context,
                                 place_span,
                                 bk,
                                 &borrow,
-                                end_issued_loan_span,
                             )
                         }
                     }
@@ -919,18 +923,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
 
                     match kind {
                         WriteKind::MutableBorrow(bk) => {
-                            let end_issued_loan_span = flow_state
-                                .borrows
-                                .operator()
-                                .opt_region_end_span(&borrow.region);
-
                             error_reported = true;
                             this.report_conflicting_borrow(
                                 context,
                                 place_span,
                                 bk,
                                 &borrow,
-                                end_issued_loan_span,
                             )
                         }
                         WriteKind::StorageDeadOrDrop => {
@@ -939,7 +937,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                                 context,
                                 borrow,
                                 place_span.1,
-                                flow_state.borrows.operator(),
                             );
                         }
                         WriteKind::Mutate => {
@@ -1141,7 +1138,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         context: Context,
         borrow: &BorrowData<'tcx>,
         span: Span,
-        flow_state: &Flows<'cx, 'gcx, 'tcx>,
     ) {
         debug!("check_for_invalidation_at_exit({:?})", borrow);
         let place = &borrow.borrowed_place;
@@ -1194,7 +1190,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 context,
                 borrow,
                 span,
-                flow_state.borrows.operator(),
             )
         }
     }
@@ -1249,36 +1244,30 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         // Two-phase borrow support: For each activation that is newly
         // generated at this statement, check if it interferes with
         // another borrow.
-        let domain = flow_state.borrows.operator();
-        let data = domain.borrows();
-        flow_state.borrows.each_gen_bit(|gen| {
-            if gen.is_activation() {
-                let borrow_index = gen.borrow_index();
-                let borrow = &data[borrow_index];
-                // currently the flow analysis registers
-                // activations for both mutable and immutable
-                // borrows. So make sure we are talking about a
-                // mutable borrow before we check it.
-                match borrow.kind {
-                    BorrowKind::Shared => return,
-                    BorrowKind::Unique | BorrowKind::Mut { .. } => {}
-                }
-
-                self.access_place(
-                    ContextKind::Activation.new(location),
-                    (&borrow.borrowed_place, span),
-                    (
-                        Deep,
-                        Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index),
-                    ),
-                    LocalMutationIsAllowed::No,
-                    flow_state,
-                );
-                // We do not need to call `check_if_path_or_subpath_is_moved`
-                // again, as we already called it when we made the
-                // initial reservation.
-            }
-        });
+        let borrow_set = self.borrow_set.clone();
+        for &borrow_index in borrow_set.activations_at_location(location) {
+            let borrow = &borrow_set[borrow_index];
+
+            // only mutable borrows should be 2-phase
+            assert!(match borrow.kind {
+                BorrowKind::Shared => false,
+                BorrowKind::Unique | BorrowKind::Mut { .. } => true,
+            });
+
+            self.access_place(
+                ContextKind::Activation.new(location),
+                (&borrow.borrowed_place, span),
+                (
+                    Deep,
+                    Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index),
+                ),
+                LocalMutationIsAllowed::No,
+                flow_state,
+            );
+            // We do not need to call `check_if_path_or_subpath_is_moved`
+            // again, as we already called it when we made the
+            // initial reservation.
+        }
     }
 }
 
@@ -2217,18 +2206,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         unreachable!("iter::repeat returned None")
     }
 
-    /// This function iterates over all of the current borrows
-    /// (represented by 1-bits in `flow_state.borrows`) that conflict
-    /// with an access to a place, invoking the `op` callback for each
-    /// one.
+    /// This function iterates over all of the in-scope borrows that
+    /// conflict with an access to a place, invoking the `op` callback
+    /// for each one.
     ///
     /// "Current borrow" here means a borrow that reaches the point in
     /// the control-flow where the access occurs.
     ///
-    /// The borrow's phase is represented by the ReserveOrActivateIndex
-    /// passed to the callback: one can call `is_reservation()` and
-    /// `is_activation()` to determine what phase the borrow is
-    /// currently in, when such distinction matters.
+    /// The borrow's phase is represented by the IsActive parameter
+    /// passed to the callback.
     fn each_borrow_involving_path<F>(
         &mut self,
         _context: Context,
@@ -2236,20 +2222,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         flow_state: &Flows<'cx, 'gcx, 'tcx>,
         mut op: F,
     ) where
-        F: FnMut(&mut Self, ReserveOrActivateIndex, &BorrowData<'tcx>) -> Control,
+        F: FnMut(&mut Self, BorrowIndex, &BorrowData<'tcx>) -> Control,
     {
         let (access, place) = access_place;
 
         // FIXME: analogous code in check_loans first maps `place` to
         // its base_path.
 
-        let data = flow_state.borrows.operator().borrows();
-
         // check for loan restricting path P being used. Accounts for
         // borrows of P, P.a.b, etc.
-        let mut iter_incoming = flow_state.borrows.iter_incoming();
-        while let Some(i) = iter_incoming.next() {
-            let borrowed = &data[i.borrow_index()];
+        let borrow_set = self.borrow_set.clone();
+        for i in flow_state.borrows_in_scope() {
+            let borrowed = &borrow_set[i];
 
             if self.places_conflict(&borrowed.borrowed_place, place, access) {
                 debug!(
@@ -2263,6 +2247,65 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             }
         }
     }
+
+    fn is_active(
+        &self,
+        borrow_data: &BorrowData<'tcx>,
+        location: Location
+    ) -> bool {
+        debug!("is_active(borrow_data={:?}, location={:?})", borrow_data, location);
+
+        // If this is not a 2-phase borrow, it is always active.
+        let activation_location = match borrow_data.activation_location {
+            Some(v) => v,
+            None => return true,
+        };
+
+        // Otherwise, it is active for every location *except* in between
+        // the reservation and the activation:
+        //
+        //       X
+        //      /
+        //     R      <--+ Except for this
+        //    / \        | diamond
+        //    \ /        |
+        //     A  <------+
+        //     |
+        //     Z
+        //
+        // Note that we assume that:
+        // - the reservation R dominates the activation A
+        // - the activation A post-dominates the reservation R (ignoring unwinding edges).
+        //
+        // This means that there can't be an edge that leaves A and
+        // comes back into that diamond unless it passes through R.
+        //
+        // Suboptimal: In some cases, this code walks the dominator
+        // tree twice when it only has to be walked once. I am
+        // lazy. -nmatsakis
+
+        // If dominated by the activation A, then it is active. The
+        // activation occurs upon entering the point A, so this is
+        // also true if location == activation_location.
+        if activation_location.dominates(location, &self.dominators) {
+            return true;
+        }
+
+        // The reservation starts *on exiting* the reservation block,
+        // so check if the location is dominated by R.successor. If so,
+        // this point falls in between the reservation and location.
+        let reserve_location = borrow_data.reserve_location.successor_within_block();
+        if reserve_location.dominates(location, &self.dominators) {
+            false
+        } else {
+            // Otherwise, this point is outside the diamond, so
+            // consider the borrow active. This could happen for
+            // example if the borrow remains active around a loop (in
+            // which case it would be active also for the point R,
+            // which would generate an error).
+            true
+        }
+    }
 }
 
 impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index 187bfc2bf90..d5e11a312ec 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -10,7 +10,7 @@
 
 use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
 use borrow_check::{Context, MirBorrowckCtxt};
-use dataflow::BorrowData;
+use borrow_check::borrow_set::BorrowData;
 use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor};
 use rustc::mir::{Local, Location, Mir};
 use rustc_data_structures::fx::FxHashSet;
@@ -29,82 +29,81 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         borrow: &BorrowData<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
     ) {
-        if let Some(regioncx) = &self.nonlexical_regioncx {
-            let mir = self.mir;
+        let regioncx = &&self.nonlexical_regioncx;
+        let mir = self.mir;
 
-            if self.nonlexical_cause_info.is_none() {
-                self.nonlexical_cause_info = Some(regioncx.compute_causal_info(mir));
-            }
+        if self.nonlexical_cause_info.is_none() {
+            self.nonlexical_cause_info = Some(regioncx.compute_causal_info(mir));
+        }
+
+        let cause_info = self.nonlexical_cause_info.as_ref().unwrap();
+        if let Some(cause) = cause_info.why_region_contains_point(borrow.region, context.loc) {
+            match *cause.root_cause() {
+                Cause::LiveVar(local, location) => {
+                    match find_regular_use(mir, regioncx, borrow, location, local) {
+                        Some(p) => {
+                            err.span_label(
+                                mir.source_info(p).span,
+                                format!("borrow later used here"),
+                            );
+                        }
+
+                        None => {
+                            span_bug!(
+                                mir.source_info(context.loc).span,
+                                "Cause should end in a LiveVar"
+                            );
+                        }
+                    }
+                }
 
-            let cause_info = self.nonlexical_cause_info.as_ref().unwrap();
-            if let Some(cause) = cause_info.why_region_contains_point(borrow.region, context.loc) {
-                match *cause.root_cause() {
-                    Cause::LiveVar(local, location) => {
-                        match find_regular_use(mir, regioncx, borrow, location, local) {
-                            Some(p) => {
+                Cause::DropVar(local, location) => {
+                    match find_drop_use(mir, regioncx, borrow, location, local) {
+                        Some(p) => match &mir.local_decls[local].name {
+                            Some(local_name) => {
                                 err.span_label(
                                     mir.source_info(p).span,
-                                    format!("borrow later used here"),
+                                    format!(
+                                        "borrow later used here, when `{}` is dropped",
+                                        local_name
+                                    ),
                                 );
                             }
-
                             None => {
-                                span_bug!(
-                                    mir.source_info(context.loc).span,
-                                    "Cause should end in a LiveVar"
+                                err.span_label(
+                                    mir.local_decls[local].source_info.span,
+                                    "borrow may end up in a temporary, created here",
                                 );
-                            }
-                        }
-                    }
 
-                    Cause::DropVar(local, location) => {
-                        match find_drop_use(mir, regioncx, borrow, location, local) {
-                            Some(p) => match &mir.local_decls[local].name {
-                                Some(local_name) => {
-                                    err.span_label(
-                                        mir.source_info(p).span,
-                                        format!(
-                                            "borrow later used here, when `{}` is dropped",
-                                            local_name
-                                        ),
-                                    );
-                                }
-                                None => {
-                                    err.span_label(
-                                        mir.local_decls[local].source_info.span,
-                                        "borrow may end up in a temporary, created here",
-                                    );
-
-                                    err.span_label(
-                                        mir.source_info(p).span,
-                                        "temporary later dropped here, \
-                                         potentially using the reference",
-                                    );
-                                }
-                            },
-
-                            None => {
-                                span_bug!(
-                                    mir.source_info(context.loc).span,
-                                    "Cause should end in a DropVar"
+                                err.span_label(
+                                    mir.source_info(p).span,
+                                    "temporary later dropped here, \
+                                     potentially using the reference",
                                 );
                             }
-                        }
-                    }
+                        },
 
-                    Cause::UniversalRegion(region_vid) => {
-                        if let Some(region) = regioncx.to_error_region(region_vid) {
-                            self.tcx.note_and_explain_free_region(
-                                err,
-                                "borrowed value must be valid for ",
-                                region,
-                                "...",
+                        None => {
+                            span_bug!(
+                                mir.source_info(context.loc).span,
+                                "Cause should end in a DropVar"
                             );
                         }
                     }
+                }
 
-                    _ => {}
+                Cause::UniversalRegion(region_vid) => {
+                    if let Some(region) = regioncx.to_error_region(region_vid) {
+                        self.tcx.note_and_explain_free_region(
+                            err,
+                            "borrowed value must be valid for ",
+                            region,
+                            "...",
+                        );
+                    }
                 }
+
+                _ => {}
             }
         }
     }
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 942e4fb56ca..3ca1bd23e86 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use borrow_check::borrow_set::BorrowSet;
 use rustc::hir::def_id::DefId;
 use rustc::mir::{ClosureRegionRequirements, ClosureOutlivesSubject, Mir};
 use rustc::infer::InferCtxt;
@@ -73,6 +74,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
     param_env: ty::ParamEnv<'gcx>,
     flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'cx, 'gcx, 'tcx>>,
     move_data: &MoveData<'tcx>,
+    _borrow_set: &BorrowSet<'tcx>,
 ) -> (
     RegionInferenceContext<'tcx>,
     Option<ClosureRegionRequirements<'gcx>>,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index faa382738b0..acd246b7031 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1611,7 +1611,7 @@ impl MirPass for TypeckMir {
 
         // When NLL is enabled, the borrow checker runs the typeck
         // itself, so we don't need this MIR pass anymore.
-        if tcx.nll() {
+        if tcx.use_mir_borrowck() {
             return;
         }
 
diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs
new file mode 100644
index 00000000000..f6ffe3c6d23
--- /dev/null
+++ b/src/librustc_mir/borrow_check/place_ext.rs
@@ -0,0 +1,60 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rustc::hir;
+use rustc::mir::ProjectionElem;
+use rustc::mir::{Local, Mir, Place};
+use rustc::ty::{self, TyCtxt};
+
+/// Extension methods for the `Place` type.
+crate trait PlaceExt<'tcx> {
+    /// True if this is a deref of a raw pointer.
+    fn is_unsafe_place(&self, tcx: TyCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>) -> bool;
+
+    /// If this is a place like `x.f.g`, returns the local
+    /// `x`. Returns `None` if this is based in a static.
+    fn root_local(&self) -> Option<Local>;
+}
+
+impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
+    fn is_unsafe_place(&self, tcx: TyCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>) -> bool {
+        match self {
+            Place::Local(_) => false,
+            Place::Static(static_) => {
+                tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable)
+            }
+            Place::Projection(proj) => match proj.elem {
+                ProjectionElem::Field(..)
+                | ProjectionElem::Downcast(..)
+                | ProjectionElem::Subslice { .. }
+                | ProjectionElem::ConstantIndex { .. }
+                | ProjectionElem::Index(_) => proj.base.is_unsafe_place(tcx, mir),
+                ProjectionElem::Deref => {
+                    let ty = proj.base.ty(mir, tcx).to_ty(tcx);
+                    match ty.sty {
+                        ty::TyRawPtr(..) => true,
+                        _ => proj.base.is_unsafe_place(tcx, mir),
+                    }
+                }
+            },
+        }
+    }
+
+    fn root_local(&self) -> Option<Local> {
+        let mut p = self;
+        loop {
+            match p {
+                Place::Projection(pi) => p = &pi.base,
+                Place::Static(_) => return None,
+                Place::Local(l) => return Some(*l),
+            }
+        }
+    }
+}
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index aa991427be0..a21691813a4 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -8,31 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use borrow_check::borrow_set::{BorrowSet, BorrowData};
+use borrow_check::place_ext::PlaceExt;
+
 use rustc;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::middle::region;
 use rustc::mir::{self, Location, Place, Mir};
-use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::ty::{self, Region, TyCtxt};
+use rustc::ty::TyCtxt;
 use rustc::ty::RegionKind;
 use rustc::ty::RegionKind::ReScope;
-use rustc::util::nodemap::{FxHashMap, FxHashSet};
 
-use rustc_data_structures::bitslice::{BitwiseOperator};
-use rustc_data_structures::indexed_set::{IdxSet};
-use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use rustc_data_structures::bitslice::BitwiseOperator;
+use rustc_data_structures::indexed_set::IdxSet;
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::sync::Lrc;
 
 use dataflow::{BitDenotation, BlockSets, InitialFlow};
-pub use dataflow::indexes::{BorrowIndex, ReserveOrActivateIndex};
+pub use dataflow::indexes::BorrowIndex;
 use borrow_check::nll::region_infer::RegionInferenceContext;
 use borrow_check::nll::ToRegionVid;
 
-use syntax_pos::Span;
-
-use std::fmt;
-use std::hash::Hash;
 use std::rc::Rc;
 
 /// `Borrows` stores the data used in the analyses that track the flow
@@ -48,534 +45,102 @@ pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
     scope_tree: Lrc<region::ScopeTree>,
     root_scope: Option<region::Scope>,
 
-    /// The fundamental map relating bitvector indexes to the borrows
-    /// in the MIR.
-    borrows: IndexVec<BorrowIndex, BorrowData<'tcx>>,
-
-    /// Each borrow is also uniquely identified in the MIR by the
-    /// `Location` of the assignment statement in which it appears on
-    /// the right hand side; we map each such location to the
-    /// corresponding `BorrowIndex`.
-    location_map: FxHashMap<Location, BorrowIndex>,
-
-    /// Every borrow in MIR is immediately stored into a place via an
-    /// assignment statement. This maps each such assigned place back
-    /// to its borrow-indexes.
-    assigned_map: FxHashMap<Place<'tcx>, FxHashSet<BorrowIndex>>,
-
-    /// Locations which activate borrows.
-    activation_map: FxHashMap<Location, FxHashSet<BorrowIndex>>,
-
-    /// Every borrow has a region; this maps each such regions back to
-    /// its borrow-indexes.
-    region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
-
-    /// Map from local to all the borrows on that local
-    local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
-
-    /// Maps regions to their corresponding source spans
-    /// Only contains ReScope()s as keys
-    region_span_map: FxHashMap<RegionKind, Span>,
+    borrow_set: Rc<BorrowSet<'tcx>>,
 
     /// NLL region inference context with which NLL queries should be resolved
-    nonlexical_regioncx: Option<Rc<RegionInferenceContext<'tcx>>>,
-}
-
-// temporarily allow some dead fields: `kind` and `region` will be
-// needed by borrowck; `borrowed_place` will probably be a MovePathIndex when
-// that is extended to include borrowed data paths.
-#[allow(dead_code)]
-#[derive(Debug)]
-pub struct BorrowData<'tcx> {
-    /// Location where the borrow reservation starts.
-    /// In many cases, this will be equal to the activation location but not always.
-    pub(crate) reserve_location: Location,
-    /// What kind of borrow this is
-    pub(crate) kind: mir::BorrowKind,
-    /// The region for which this borrow is live
-    pub(crate) region: Region<'tcx>,
-    /// Place from which we are borrowing
-    pub(crate) borrowed_place: mir::Place<'tcx>,
-    /// Place to which the borrow was stored
-    pub(crate) assigned_place: mir::Place<'tcx>,
-}
-
-impl<'tcx> fmt::Display for BorrowData<'tcx> {
-    fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
-        let kind = match self.kind {
-            mir::BorrowKind::Shared => "",
-            mir::BorrowKind::Unique => "uniq ",
-            mir::BorrowKind::Mut { .. } => "mut ",
-        };
-        let region = format!("{}", self.region);
-        let region = if region.len() > 0 { format!("{} ", region) } else { region };
-        write!(w, "&{}{}{:?}", region, kind, self.borrowed_place)
-    }
-}
-
-impl ReserveOrActivateIndex {
-    fn reserved(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new(i.index() * 2) }
-    fn active(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new((i.index() * 2) + 1) }
-
-    pub(crate) fn is_reservation(self) -> bool { self.index() % 2 == 0 }
-    pub(crate) fn is_activation(self) -> bool { self.index() % 2 == 1}
-
-    pub(crate) fn kind(self) -> &'static str {
-        if self.is_reservation() { "reserved" } else { "active" }
-    }
-    pub(crate) fn borrow_index(self) -> BorrowIndex {
-        BorrowIndex::new(self.index() / 2)
-    }
+    nonlexical_regioncx: Rc<RegionInferenceContext<'tcx>>,
 }
 
 impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
-    pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-               mir: &'a Mir<'tcx>,
-               nonlexical_regioncx: Option<Rc<RegionInferenceContext<'tcx>>>,
-               def_id: DefId,
-               body_id: Option<hir::BodyId>)
-               -> Self {
+    crate fn new(
+        tcx: TyCtxt<'a, 'gcx, 'tcx>,
+        mir: &'a Mir<'tcx>,
+        nonlexical_regioncx: Rc<RegionInferenceContext<'tcx>>,
+        def_id: DefId,
+        body_id: Option<hir::BodyId>,
+        borrow_set: &Rc<BorrowSet<'tcx>>
+    ) -> Self {
         let scope_tree = tcx.region_scope_tree(def_id);
         let root_scope = body_id.map(|body_id| {
             region::Scope::CallSite(tcx.hir.body(body_id).value.hir_id.local_id)
         });
-        let mut visitor = GatherBorrows {
-            tcx,
-            mir,
-            idx_vec: IndexVec::new(),
-            location_map: FxHashMap(),
-            assigned_map: FxHashMap(),
-            activation_map: FxHashMap(),
-            region_map: FxHashMap(),
-            local_map: FxHashMap(),
-            region_span_map: FxHashMap(),
-            nonlexical_regioncx: nonlexical_regioncx.clone()
-        };
-        visitor.visit_mir(mir);
-        return Borrows { tcx: tcx,
-                         mir: mir,
-                         borrows: visitor.idx_vec,
-                         scope_tree,
-                         root_scope,
-                         location_map: visitor.location_map,
-                         assigned_map: visitor.assigned_map,
-                         activation_map: visitor.activation_map,
-                         region_map: visitor.region_map,
-                         local_map: visitor.local_map,
-                         region_span_map: visitor.region_span_map,
-                         nonlexical_regioncx };
-
-        struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
-            tcx: TyCtxt<'a, 'gcx, 'tcx>,
-            mir: &'a Mir<'tcx>,
-            idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>,
-            location_map: FxHashMap<Location, BorrowIndex>,
-            assigned_map: FxHashMap<Place<'tcx>, FxHashSet<BorrowIndex>>,
-            activation_map: FxHashMap<Location, FxHashSet<BorrowIndex>>,
-            region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
-            local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
-            region_span_map: FxHashMap<RegionKind, Span>,
-            nonlexical_regioncx: Option<Rc<RegionInferenceContext<'tcx>>>,
-        }
-
-        impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
-            fn visit_assign(&mut self,
-                            block: mir::BasicBlock,
-                            assigned_place: &mir::Place<'tcx>,
-                            rvalue: &mir::Rvalue<'tcx>,
-                            location: mir::Location) {
-                fn root_local(mut p: &mir::Place<'_>) -> Option<mir::Local> {
-                    loop { match p {
-                        mir::Place::Projection(pi) => p = &pi.base,
-                        mir::Place::Static(_) => return None,
-                        mir::Place::Local(l) => return Some(*l)
-                    }}
-                }
-
-                if let mir::Rvalue::Ref(region, kind, ref borrowed_place) = *rvalue {
-                    if is_unsafe_place(self.tcx, self.mir, borrowed_place) { return; }
-
-                    let activate_location = self.compute_activation_location(location,
-                                                                             &assigned_place,
-                                                                             region,
-                                                                             kind);
-                    let borrow = BorrowData {
-                        kind, region,
-                        reserve_location: location,
-                        borrowed_place: borrowed_place.clone(),
-                        assigned_place: assigned_place.clone(),
-                    };
-                    let idx = self.idx_vec.push(borrow);
-                    self.location_map.insert(location, idx);
-
-                    insert(&mut self.activation_map, &activate_location, idx);
-                    insert(&mut self.assigned_map, assigned_place, idx);
-                    insert(&mut self.region_map, &region, idx);
-                    if let Some(local) = root_local(borrowed_place) {
-                        insert(&mut self.local_map, &local, idx);
-                    }
-                }
-
-                return self.super_assign(block, assigned_place, rvalue, location);
-
-                fn insert<'a, K, V>(map: &'a mut FxHashMap<K, FxHashSet<V>>,
-                                    k: &K,
-                                    v: V)
-                    where K: Clone+Eq+Hash, V: Eq+Hash
-                {
-                    map.entry(k.clone())
-                        .or_insert(FxHashSet())
-                        .insert(v);
-                }
-            }
-
-            fn visit_rvalue(&mut self,
-                            rvalue: &mir::Rvalue<'tcx>,
-                            location: mir::Location) {
-                if let mir::Rvalue::Ref(region, kind, ref place) = *rvalue {
-                    // double-check that we already registered a BorrowData for this
-
-                    let mut found_it = false;
-                    for idx in &self.region_map[region] {
-                        let bd = &self.idx_vec[*idx];
-                        if bd.reserve_location == location &&
-                            bd.kind == kind &&
-                            bd.region == region &&
-                            bd.borrowed_place == *place
-                        {
-                            found_it = true;
-                            break;
-                        }
-                    }
-                    assert!(found_it, "Ref {:?} at {:?} missing BorrowData", rvalue, location);
-                }
-
-                return self.super_rvalue(rvalue, location);
-            }
-
-            fn visit_statement(&mut self,
-                               block: mir::BasicBlock,
-                               statement: &mir::Statement<'tcx>,
-                               location: Location) {
-                if let mir::StatementKind::EndRegion(region_scope) = statement.kind {
-                    self.region_span_map.insert(ReScope(region_scope), statement.source_info.span);
-                }
-                return self.super_statement(block, statement, location);
-            }
-        }
-
-        /// A MIR visitor that determines if a specific place is used in a two-phase activating
-        /// manner in a given chunk of MIR.
-        struct ContainsUseOfPlace<'b, 'tcx: 'b> {
-            target: &'b Place<'tcx>,
-            use_found: bool,
-        }
-
-        impl<'b, 'tcx: 'b> ContainsUseOfPlace<'b, 'tcx> {
-            fn new(place: &'b Place<'tcx>) -> Self {
-                Self { target: place, use_found: false }
-            }
-
-            /// return whether `context` should be considered a "use" of a
-            /// place found in that context. "Uses" activate associated
-            /// borrows (at least when such uses occur while the borrow also
-            /// has a reservation at the time).
-            fn is_potential_use(context: PlaceContext) -> bool {
-                match context {
-                    // storage effects on a place do not activate it
-                    PlaceContext::StorageLive | PlaceContext::StorageDead => false,
-
-                    // validation effects do not activate a place
-                    //
-                    // FIXME: Should they? Is it just another read? Or can we
-                    // guarantee it won't dereference the stored address? How
-                    // "deep" does validation go?
-                    PlaceContext::Validate => false,
-
-                    // FIXME: This is here to not change behaviour from before
-                    // AsmOutput existed, but it's not necessarily a pure overwrite.
-                    // so it's possible this should activate the place.
-                    PlaceContext::AsmOutput |
-                    // pure overwrites of a place do not activate it. (note
-                    // PlaceContext::Call is solely about dest place)
-                    PlaceContext::Store | PlaceContext::Call => false,
-
-                    // reads of a place *do* activate it
-                    PlaceContext::Move |
-                    PlaceContext::Copy |
-                    PlaceContext::Drop |
-                    PlaceContext::Inspect |
-                    PlaceContext::Borrow { .. } |
-                    PlaceContext::Projection(..) => true,
-                }
-            }
-        }
-
-        impl<'b, 'tcx: 'b> Visitor<'tcx> for ContainsUseOfPlace<'b, 'tcx> {
-            fn visit_place(&mut self,
-                           place: &mir::Place<'tcx>,
-                           context: PlaceContext<'tcx>,
-                           location: Location) {
-                if Self::is_potential_use(context) && place == self.target {
-                    self.use_found = true;
-                    return;
-                    // There is no need to keep checking the statement, we already found a use
-                }
-
-                self.super_place(place, context, location);
-            }
-        }
-
-        impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
-            /// Returns true if the borrow represented by `kind` is
-            /// allowed to be split into separate Reservation and
-            /// Activation phases.
-            fn allow_two_phase_borrow(&self, kind: mir::BorrowKind) -> bool {
-                self.tcx.two_phase_borrows() &&
-                    (kind.allows_two_phase_borrow() ||
-                     self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref)
-            }
-
-            /// Returns true if the given location contains an NLL-activating use of the given place
-            fn location_contains_use(&self, location: Location, place: &Place) -> bool {
-                let mut use_checker = ContainsUseOfPlace::new(place);
-                let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| {
-                    panic!("could not find block at location {:?}", location);
-                });
-                if location.statement_index != block.statements.len() {
-                    // This is a statement
-                    let stmt = block.statements.get(location.statement_index).unwrap_or_else(|| {
-                        panic!("could not find statement at location {:?}");
-                    });
-                    use_checker.visit_statement(location.block, stmt, location);
-                } else {
-                    // This is a terminator
-                    match block.terminator {
-                        Some(ref term) => {
-                            use_checker.visit_terminator(location.block, term, location);
-                        }
-                        None => {
-                            // There is no way for Place to be used by the terminator if there is no
-                            // terminator
-                        }
-                    }
-                }
-
-                use_checker.use_found
-            }
-
-            /// Determines if the provided region is terminated after the provided location.
-            /// EndRegion statements terminate their enclosed region::Scope.
-            /// We also consult with the NLL region inference engine, should one be available
-            fn region_terminated_after(&self, region: Region<'tcx>, location: Location) -> bool {
-                let block_data = &self.mir[location.block];
-                if location.statement_index != block_data.statements.len() {
-                    let stmt = &block_data.statements[location.statement_index];
-                    if let mir::StatementKind::EndRegion(region_scope) = stmt.kind {
-                        if &ReScope(region_scope) == region {
-                            // We encountered an EndRegion statement that terminates the provided
-                            // region
-                            return true;
-                        }
-                    }
-                }
-                if let Some(ref regioncx) = self.nonlexical_regioncx {
-                    if !regioncx.region_contains_point(region, location) {
-                        // NLL says the region has ended already
-                        return true;
-                    }
-                }
-
-                false
-            }
-
-            /// Computes the activation location of a borrow.
-            /// The general idea is to start at the beginning of the region and perform a DFS
-            /// until we exit the region, either via an explicit EndRegion or because NLL tells
-            /// us so. If we find more than one valid activation point, we currently panic the
-            /// compiler since two-phase borrows are only currently supported for compiler-
-            /// generated code. More precisely, we only allow two-phase borrows for:
-            ///   - Function calls (fn some_func(&mut self, ....))
-            ///   - *Assign operators (a += b -> fn add_assign(&mut self, other: Self))
-            /// See
-            ///   - https://github.com/rust-lang/rust/issues/48431
-            /// for detailed design notes.
-            /// See the FIXME in the body of the function for notes on extending support to more
-            /// general two-phased borrows.
-            fn compute_activation_location(&self,
-                                           start_location: Location,
-                                           assigned_place: &mir::Place<'tcx>,
-                                           region: Region<'tcx>,
-                                           kind: mir::BorrowKind) -> Location {
-                debug!("Borrows::compute_activation_location({:?}, {:?}, {:?})",
-                       start_location,
-                       assigned_place,
-                       region);
-                if !self.allow_two_phase_borrow(kind) {
-                    debug!("  -> {:?}", start_location);
-                    return start_location;
-                }
-
-                // Perform the DFS.
-                // `stack` is the stack of locations still under consideration
-                // `visited` is the set of points we have already visited
-                // `found_use` is an Option that becomes Some when we find a use
-                let mut stack = vec![start_location];
-                let mut visited = FxHashSet();
-                let mut found_use = None;
-                while let Some(curr_loc) = stack.pop() {
-                    let block_data = &self.mir.basic_blocks()
-                        .get(curr_loc.block)
-                        .unwrap_or_else(|| {
-                            panic!("could not find block at location {:?}", curr_loc);
-                        });
-
-                    if self.region_terminated_after(region, curr_loc) {
-                        // No need to process this statement.
-                        // It's either an EndRegion (and thus couldn't use assigned_place) or not
-                        // contained in the NLL region and thus a use would be invalid
-                        continue;
-                    }
-
-                    if !visited.insert(curr_loc) {
-                        debug!("  Already visited {:?}", curr_loc);
-                        continue;
-                    }
-
-                    if self.location_contains_use(curr_loc, assigned_place) {
-                        // FIXME: Handle this case a little more gracefully. Perhaps collect
-                        // all uses in a vector, and find the point in the CFG that dominates
-                        // all of them?
-                        // Right now this is sufficient though since there should only be exactly
-                        // one borrow-activating use of the borrow.
-                        assert!(found_use.is_none(), "Found secondary use of place");
-                        found_use = Some(curr_loc);
-                    }
-
-                    // Push the points we should consider next.
-                    if curr_loc.statement_index < block_data.statements.len() {
-                        stack.push(curr_loc.successor_within_block());
-                    } else {
-                        stack.extend(block_data.terminator().successors().iter().map(
-                            |&basic_block| {
-                                Location {
-                                    statement_index: 0,
-                                    block: basic_block
-                                }
-                            }
-                        ))
-                    }
-                }
 
-                let found_use = found_use.expect("Did not find use of two-phase place");
-                debug!("  -> {:?}", found_use);
-                found_use
-            }
-        }
-    }
-
-    /// Returns the span for the "end point" given region. This will
-    /// return `None` if NLL is enabled, since that concept has no
-    /// meaning there.  Otherwise, return region span if it exists and
-    /// span for end of the function if it doesn't exist.
-    pub(crate) fn opt_region_end_span(&self, region: &Region) -> Option<Span> {
-        match self.nonlexical_regioncx {
-            Some(_) => None,
-            None => {
-                match self.region_span_map.get(region) {
-                    Some(span) => Some(self.tcx.sess.codemap().end_point(*span)),
-                    None => Some(self.tcx.sess.codemap().end_point(self.mir.span))
-                }
-            }
+        Borrows {
+            tcx: tcx,
+            mir: mir,
+            borrow_set: borrow_set.clone(),
+            scope_tree,
+            root_scope,
+            nonlexical_regioncx,
         }
     }
 
-    pub fn borrows(&self) -> &IndexVec<BorrowIndex, BorrowData<'tcx>> { &self.borrows }
+    crate fn borrows(&self) -> &IndexVec<BorrowIndex, BorrowData<'tcx>> { &self.borrow_set.borrows }
 
     pub fn scope_tree(&self) -> &Lrc<region::ScopeTree> { &self.scope_tree }
 
     pub fn location(&self, idx: BorrowIndex) -> &Location {
-        &self.borrows[idx].reserve_location
+        &self.borrow_set.borrows[idx].reserve_location
     }
 
     /// Add all borrows to the kill set, if those borrows are out of scope at `location`.
     /// That means either they went out of either a nonlexical scope, if we care about those
     /// at the moment, or the location represents a lexical EndRegion
     fn kill_loans_out_of_scope_at_location(&self,
-                                           sets: &mut BlockSets<ReserveOrActivateIndex>,
+                                           sets: &mut BlockSets<BorrowIndex>,
                                            location: Location) {
-        if let Some(ref regioncx) = self.nonlexical_regioncx {
-            // NOTE: The state associated with a given `location`
-            // reflects the dataflow on entry to the statement. If it
-            // does not contain `borrow_region`, then then that means
-            // that the statement at `location` kills the borrow.
-            //
-            // We are careful always to call this function *before* we
-            // set up the gen-bits for the statement or
-            // termanator. That way, if the effect of the statement or
-            // terminator *does* introduce a new loan of the same
-            // region, then setting that gen-bit will override any
-            // potential kill introduced here.
-            for (borrow_index, borrow_data) in self.borrows.iter_enumerated() {
-                let borrow_region = borrow_data.region.to_region_vid();
-                if !regioncx.region_contains_point(borrow_region, location) {
-                    sets.kill(&ReserveOrActivateIndex::reserved(borrow_index));
-                    sets.kill(&ReserveOrActivateIndex::active(borrow_index));
-                }
+        let regioncx = &self.nonlexical_regioncx;
+
+        // NOTE: The state associated with a given `location`
+        // reflects the dataflow on entry to the statement. If it
+        // does not contain `borrow_region`, then then that means
+        // that the statement at `location` kills the borrow.
+        //
+        // We are careful always to call this function *before* we
+        // set up the gen-bits for the statement or
+        // termanator. That way, if the effect of the statement or
+        // terminator *does* introduce a new loan of the same
+        // region, then setting that gen-bit will override any
+        // potential kill introduced here.
+        for (borrow_index, borrow_data) in self.borrow_set.borrows.iter_enumerated() {
+            let borrow_region = borrow_data.region.to_region_vid();
+            if !regioncx.region_contains_point(borrow_region, location) {
+                sets.kill(&borrow_index);
             }
         }
     }
 
     fn kill_borrows_on_local(&self,
-                             sets: &mut BlockSets<ReserveOrActivateIndex>,
+                             sets: &mut BlockSets<BorrowIndex>,
                              local: &rustc::mir::Local)
     {
-        if let Some(borrow_indexes) = self.local_map.get(local) {
-            sets.kill_all(borrow_indexes.iter()
-                          .map(|b| ReserveOrActivateIndex::reserved(*b)));
-            sets.kill_all(borrow_indexes.iter()
-                          .map(|b| ReserveOrActivateIndex::active(*b)));
-        }
-    }
-
-    /// Performs the activations for a given location
-    fn perform_activations_at_location(&self,
-                                       sets: &mut BlockSets<ReserveOrActivateIndex>,
-                                       location: Location) {
-        // Handle activations
-        match self.activation_map.get(&location) {
-            Some(activations) => {
-                for activated in activations {
-                    debug!("activating borrow {:?}", activated);
-                    sets.gen(&ReserveOrActivateIndex::active(*activated))
-                }
-            }
-            None => {}
+        if let Some(borrow_indexes) = self.borrow_set.local_map.get(local) {
+            sets.kill_all(borrow_indexes);
         }
     }
 }
 
 impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
-    type Idx = ReserveOrActivateIndex;
+    type Idx = BorrowIndex;
     fn name() -> &'static str { "borrows" }
     fn bits_per_block(&self) -> usize {
-        self.borrows.len() * 2
+        self.borrow_set.borrows.len() * 2
     }
 
-    fn start_block_effect(&self, _entry_set: &mut IdxSet<ReserveOrActivateIndex>) {
+    fn start_block_effect(&self, _entry_set: &mut IdxSet<BorrowIndex>) {
         // no borrows of code region_scopes have been taken prior to
         // function execution, so this method has no effect on
         // `_sets`.
     }
 
     fn before_statement_effect(&self,
-                               sets: &mut BlockSets<ReserveOrActivateIndex>,
+                               sets: &mut BlockSets<BorrowIndex>,
                                location: Location) {
         debug!("Borrows::before_statement_effect sets: {:?} location: {:?}", sets, location);
         self.kill_loans_out_of_scope_at_location(sets, location);
     }
 
-    fn statement_effect(&self, sets: &mut BlockSets<ReserveOrActivateIndex>, location: Location) {
+    fn statement_effect(&self, sets: &mut BlockSets<BorrowIndex>, location: Location) {
         debug!("Borrows::statement_effect sets: {:?} location: {:?}", sets, location);
 
         let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| {
@@ -585,21 +150,10 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
             panic!("could not find statement at location {:?}");
         });
 
-        self.perform_activations_at_location(sets, location);
         self.kill_loans_out_of_scope_at_location(sets, location);
 
         match stmt.kind {
-            // EndRegion kills any borrows (reservations and active borrows both)
-            mir::StatementKind::EndRegion(region_scope) => {
-                if let Some(borrow_indexes) = self.region_map.get(&ReScope(region_scope)) {
-                    assert!(self.nonlexical_regioncx.is_none());
-                    for idx in borrow_indexes {
-                        sets.kill(&ReserveOrActivateIndex::reserved(*idx));
-                        sets.kill(&ReserveOrActivateIndex::active(*idx));
-                    }
-                } else {
-                    // (if there is no entry, then there are no borrows to be tracked)
-                }
+            mir::StatementKind::EndRegion(_) => {
             }
 
             mir::StatementKind::Assign(ref lhs, ref rhs) => {
@@ -617,22 +171,22 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
                 // propagate_call_return method.
 
                 if let mir::Rvalue::Ref(region, _, ref place) = *rhs {
-                    if is_unsafe_place(self.tcx, self.mir, place) { return; }
-                    let index = self.location_map.get(&location).unwrap_or_else(|| {
+                    if place.is_unsafe_place(self.tcx, self.mir) { return; }
+                    let index = self.borrow_set.location_map.get(&location).unwrap_or_else(|| {
                         panic!("could not find BorrowIndex for location {:?}", location);
                     });
 
                     if let RegionKind::ReEmpty = region {
                         // If the borrowed value dies before the borrow is used, the region for
                         // the borrow can be empty. Don't track the borrow in that case.
-                        sets.kill(&ReserveOrActivateIndex::active(*index));
+                        sets.kill(&index);
                         return
                     }
 
-                    assert!(self.region_map.get(region).unwrap_or_else(|| {
+                    assert!(self.borrow_set.region_map.get(region).unwrap_or_else(|| {
                         panic!("could not find BorrowIndexs for region {:?}", region);
                     }).contains(&index));
-                    sets.gen(&ReserveOrActivateIndex::reserved(*index));
+                    sets.gen(&index);
 
                     // Issue #46746: Two-phase borrows handles
                     // stmts of form `Tmp = &mut Borrow` ...
@@ -643,7 +197,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
                             // e.g. `box (&mut _)`. Current
                             // conservative solution: force
                             // immediate activation here.
-                            sets.gen(&ReserveOrActivateIndex::active(*index));
+                            sets.gen(&index);
                         }
                     }
                 }
@@ -679,13 +233,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
     }
 
     fn before_terminator_effect(&self,
-                                sets: &mut BlockSets<ReserveOrActivateIndex>,
+                                sets: &mut BlockSets<BorrowIndex>,
                                 location: Location) {
         debug!("Borrows::before_terminator_effect sets: {:?} location: {:?}", sets, location);
         self.kill_loans_out_of_scope_at_location(sets, location);
     }
 
-    fn terminator_effect(&self, sets: &mut BlockSets<ReserveOrActivateIndex>, location: Location) {
+    fn terminator_effect(&self, sets: &mut BlockSets<BorrowIndex>, location: Location) {
         debug!("Borrows::terminator_effect sets: {:?} location: {:?}", sets, location);
 
         let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| {
@@ -693,7 +247,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
         });
 
         let term = block.terminator();
-        self.perform_activations_at_location(sets, location);
         self.kill_loans_out_of_scope_at_location(sets, location);
 
 
@@ -707,7 +260,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
                 // and hence most of these loans will already be dead -- but, in some cases
                 // like unwind paths, we do not always emit `EndRegion` statements, so we
                 // add some kills here as a "backup" and to avoid spurious error messages.
-                for (borrow_index, borrow_data) in self.borrows.iter_enumerated() {
+                for (borrow_index, borrow_data) in self.borrow_set.borrows.iter_enumerated() {
                     if let ReScope(scope) = borrow_data.region {
                         // Check that the scope is not actually a scope from a function that is
                         // a parent of our closure. Note that the CallSite scope itself is
@@ -716,8 +269,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
                             if *scope != root_scope &&
                                 self.scope_tree.is_subscope_of(*scope, root_scope)
                             {
-                                sets.kill(&ReserveOrActivateIndex::reserved(borrow_index));
-                                sets.kill(&ReserveOrActivateIndex::active(borrow_index));
+                                sets.kill(&borrow_index);
                             }
                         }
                     }
@@ -738,7 +290,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
     }
 
     fn propagate_call_return(&self,
-                             _in_out: &mut IdxSet<ReserveOrActivateIndex>,
+                             _in_out: &mut IdxSet<BorrowIndex>,
                              _call_bb: mir::BasicBlock,
                              _dest_bb: mir::BasicBlock,
                              _dest_place: &mir::Place) {
@@ -764,34 +316,3 @@ impl<'a, 'gcx, 'tcx> InitialFlow for Borrows<'a, 'gcx, 'tcx> {
     }
 }
 
-fn is_unsafe_place<'a, 'gcx: 'tcx, 'tcx: 'a>(
-    tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    mir: &'a Mir<'tcx>,
-    place: &mir::Place<'tcx>
-) -> bool {
-    use self::mir::Place::*;
-    use self::mir::ProjectionElem;
-
-    match *place {
-        Local(_) => false,
-        Static(ref static_) => tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable),
-        Projection(ref proj) => {
-            match proj.elem {
-                ProjectionElem::Field(..) |
-                ProjectionElem::Downcast(..) |
-                ProjectionElem::Subslice { .. } |
-                ProjectionElem::ConstantIndex { .. } |
-                ProjectionElem::Index(_) => {
-                    is_unsafe_place(tcx, mir, &proj.base)
-                }
-                ProjectionElem::Deref => {
-                    let ty = proj.base.ty(mir, tcx).to_ty(tcx);
-                    match ty.sty {
-                        ty::TyRawPtr(..) => true,
-                        _ => is_unsafe_place(tcx, mir, &proj.base),
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs
index 287640439c0..f64fd64b283 100644
--- a/src/librustc_mir/dataflow/impls/mod.rs
+++ b/src/librustc_mir/dataflow/impls/mod.rs
@@ -19,6 +19,7 @@ use rustc_data_structures::indexed_set::{IdxSet};
 use rustc_data_structures::indexed_vec::Idx;
 
 use super::MoveDataParamEnv;
+
 use util::elaborate_drops::DropFlagState;
 
 use super::move_paths::{HasMoveData, MoveData, MoveOutIndex, MovePathIndex, InitIndex};
@@ -37,7 +38,6 @@ mod borrowed_locals;
 
 pub use self::borrowed_locals::*;
 
-#[allow(dead_code)]
 pub(super) mod borrows;
 
 /// `MaybeInitializedPlaces` tracks all places that might be
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 454b6cbd27d..85458c7d684 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -29,9 +29,8 @@ pub use self::impls::{MaybeStorageLive};
 pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
 pub use self::impls::{DefinitelyInitializedPlaces, MovingOutStatements};
 pub use self::impls::EverInitializedPlaces;
-pub use self::impls::borrows::{Borrows, BorrowData};
+pub use self::impls::borrows::Borrows;
 pub use self::impls::HaveBeenBorrowedLocals;
-pub(crate) use self::impls::borrows::{ReserveOrActivateIndex};
 pub use self::at_location::{FlowAtLocation, FlowsAtLocation};
 pub(crate) use self::drop_flag_effects::*;
 
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index 9f6cf8c036e..3a49e28f041 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -65,9 +65,6 @@ pub(crate) mod indexes {
 
     /// Index into Borrows.locations
     new_index!(BorrowIndex, "bw");
-
-    /// Index into Reservations/Activations bitvector
-    new_index!(ReserveOrActivateIndex, "ra");
 }
 
 pub use self::indexes::MovePathIndex;
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index a701fe31442..de3063a5756 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -20,6 +20,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(catch_expr)]
+#![feature(crate_visibility_modifier)]
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
 #![feature(decl_macro)]
diff --git a/src/test/compile-fail/E0501.rs b/src/test/compile-fail/E0501.rs
index f7e246e8f0f..5643e1ef091 100644
--- a/src/test/compile-fail/E0501.rs
+++ b/src/test/compile-fail/E0501.rs
@@ -26,10 +26,12 @@ fn foo(a: &mut i32) {
         inside_closure(a)
     };
     outside_closure_1(a); //[ast]~ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
-                         //[mir]~^ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
+    //[mir]~^ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
 
     outside_closure_2(a); //[ast]~ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
-                         //[mir]~^ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
+    //[mir]~^ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
+
+    drop(bar);
 }
 
 fn main() {
diff --git a/src/test/compile-fail/borrowck/borrowck-asm.rs b/src/test/compile-fail/borrowck/borrowck-asm.rs
index 9ad3a8f9fc8..0b230be85ad 100644
--- a/src/test/compile-fail/borrowck/borrowck-asm.rs
+++ b/src/test/compile-fail/borrowck/borrowck-asm.rs
@@ -14,7 +14,7 @@
 // ignore-sparc
 
 // revisions: ast mir
-//[mir]compile-flags: -Z borrowck=mir -Z nll
+//[mir]compile-flags: -Z borrowck=mir
 
 #![feature(asm)]
 
diff --git a/src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs b/src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs
index f498d8d500e..9057ba07907 100644
--- a/src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs
+++ b/src/test/compile-fail/borrowck/borrowck-closures-mut-and-imm.rs
@@ -29,7 +29,8 @@ fn a() {
     let mut x = 3;
     let c1 = || x = 4;
     let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
-                       //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+    //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+    drop(c1);
 }
 
 fn b() {
@@ -37,6 +38,7 @@ fn b() {
     let c1 = || set(&mut x);
     let c2 = || get(&x); //[ast]~ ERROR cannot borrow `x`
                          //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+    drop(c1);
 }
 
 fn c() {
@@ -44,6 +46,7 @@ fn c() {
     let c1 = || set(&mut x);
     let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
                        //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+    drop(c1);
 }
 
 fn d() {
@@ -51,6 +54,7 @@ fn d() {
     let c2 = || x * 5;
     x = 5; //[ast]~ ERROR cannot assign
            //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+    drop(c2);
 }
 
 fn e() {
@@ -58,6 +62,7 @@ fn e() {
     let c1 = || get(&x);
     x = 5; //[ast]~ ERROR cannot assign
            //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+    drop(c1);
 }
 
 fn f() {
@@ -65,6 +70,7 @@ fn f() {
     let c1 = || get(&*x);
     *x = 5; //[ast]~ ERROR cannot assign to `*x`
             //[mir]~^ ERROR cannot assign to `*x` because it is borrowed
+    drop(c1);
 }
 
 fn g() {
@@ -76,6 +82,7 @@ fn g() {
     let c1 = || get(&*x.f);
     *x.f = 5; //[ast]~ ERROR cannot assign to `*x.f`
               //[mir]~^ ERROR cannot assign to `*x.f` because it is borrowed
+    drop(c1);
 }
 
 fn h() {
@@ -87,6 +94,7 @@ fn h() {
     let c1 = || get(&*x.f);
     let c2 = || *x.f = 5; //[ast]~ ERROR cannot borrow `x` as mutable
                           //[mir]~^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable
+    drop(c1);
 }
 
 fn main() {
diff --git a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
index fa475949b36..3a7e4a13740 100644
--- a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
+++ b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
@@ -49,83 +49,93 @@ fn main() {
     // Local and field from struct
     {
         let mut f = Foo { x: 22 };
-        let _x = f.x();
+        let x = f.x();
         f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
-             //[mir]~^ ERROR cannot use `f.x` because it was mutably borrowed
+        //[mir]~^ ERROR cannot use `f.x` because it was mutably borrowed
+        drop(x);
     }
     // Local and field from tuple-struct
     {
         let mut g = Bar(22);
-        let _0 = g.x();
+        let x = g.x();
         g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
              //[mir]~^ ERROR cannot use `g.0` because it was mutably borrowed
+        drop(x);
     }
     // Local and field from tuple
     {
         let mut h = (22, 23);
-        let _0 = &mut h.0;
+        let x = &mut h.0;
         h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
              //[mir]~^ ERROR cannot use `h.0` because it was mutably borrowed
+        drop(x);
     }
     // Local and field from enum
     {
         let mut e = Baz::X(2);
-        let _e0 = e.x();
+        let x = e.x();
         match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
             Baz::X(value) => value
             //[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed
             //[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed
         };
+        drop(x);
     }
     // Local and field from union
     unsafe {
         let mut u = U { b: 0 };
-        let _ra = &mut u.a;
+        let x = &mut u.a;
         u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
              //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
+        drop(x);
     }
     // Deref and field from struct
     {
         let mut f = Box::new(Foo { x: 22 });
-        let _x = f.x();
+        let x = f.x();
         f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
              //[mir]~^ ERROR cannot use `f.x` because it was mutably borrowed
+        drop(x);
     }
     // Deref and field from tuple-struct
     {
         let mut g = Box::new(Bar(22));
-        let _0 = g.x();
+        let x = g.x();
         g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
              //[mir]~^ ERROR cannot use `g.0` because it was mutably borrowed
+        drop(x);
     }
     // Deref and field from tuple
     {
         let mut h = Box::new((22, 23));
-        let _0 = &mut h.0;
+        let x = &mut h.0;
         h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
              //[mir]~^ ERROR cannot use `h.0` because it was mutably borrowed
+        drop(x);
     }
     // Deref and field from enum
     {
         let mut e = Box::new(Baz::X(3));
-        let _e0 = e.x();
+        let x = e.x();
         match *e { //[mir]~ ERROR cannot use `*e` because it was mutably borrowed
             Baz::X(value) => value
             //[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed
             //[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed
         };
+        drop(x);
     }
     // Deref and field from union
     unsafe {
         let mut u = Box::new(U { b: 0 });
-        let _ra = &mut u.a;
+        let x = &mut u.a;
         u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
              //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
+        drop(x);
     }
     // Constant index
     {
         let mut v = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-        let _v = &mut v;
+        let x = &mut v;
         match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[x, _, .., _, _] => println!("{}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
@@ -150,11 +160,12 @@ fn main() {
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
                             _ => panic!("other case"),
         }
+        drop(x);
     }
     // Subslices
     {
         let mut v = &[1, 2, 3, 4, 5];
-        let _v = &mut v;
+        let x = &mut v;
         match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[x..] => println!("{:?}", x),
                 //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed
@@ -179,13 +190,14 @@ fn main() {
                 //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed
             _ => panic!("other case"),
         }
+        drop(x);
     }
     // Downcasted field
     {
         enum E<X> { A(X), B { x: X } }
 
         let mut e = E::A(3);
-        let _e = &mut e;
+        let x = &mut e;
         match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed
             E::A(ref ax) =>
                 //[ast]~^ ERROR cannot borrow `e.0` as immutable because `e` is also borrowed as mutable
@@ -197,13 +209,14 @@ fn main() {
                 //[mir]~^^ ERROR cannot borrow `e.x` as immutable because it is also borrowed as mutable
                 println!("e.bx: {:?}", bx),
         }
+        drop(x);
     }
     // Field in field
     {
         struct F { x: u32, y: u32 };
         struct S { x: F, y: (u32, u32), };
         let mut s = S { x: F { x: 1, y: 2}, y: (999, 998) };
-        let _s = &mut s;
+        let x = &mut s;
         match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed
             S  { y: (ref y0, _), .. } =>
                 //[ast]~^ ERROR cannot borrow `s.y.0` as immutable because `s` is also borrowed as mutable
@@ -218,6 +231,7 @@ fn main() {
                 println!("x0: {:?}", x0),
             _ => panic!("other case"),
         }
+        drop(x);
     }
     // Field of ref
     {
@@ -231,6 +245,7 @@ fn main() {
             let p: &'a u8 = &*block.current;
             //[mir]~^ ERROR cannot borrow `*block.current` as immutable because it is also borrowed as mutable
             // No errors in AST because of issue rust#38899
+            drop(x);
         }
     }
     // Field of ptr
@@ -245,29 +260,32 @@ fn main() {
             let p : *const u8 = &*(*block).current;
             //[mir]~^ ERROR cannot borrow `*block.current` as immutable because it is also borrowed as mutable
             // No errors in AST because of issue rust#38899
+            drop(x);
         }
     }
     // Field of index
     {
         struct F {x: u32, y: u32};
         let mut v = &[F{x: 1, y: 2}, F{x: 3, y: 4}];
-        let _v = &mut v;
+        let x = &mut v;
         v[0].y;
         //[ast]~^ ERROR cannot use `v[..].y` because it was mutably borrowed
         //[mir]~^^ ERROR cannot use `v[..].y` because it was mutably borrowed
         //[mir]~| ERROR cannot use `*v` because it was mutably borrowed
+        drop(x);
     }
     // Field of constant index
     {
         struct F {x: u32, y: u32};
         let mut v = &[F{x: 1, y: 2}, F{x: 3, y: 4}];
-        let _v = &mut v;
+        let x = &mut v;
         match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed
             &[_, F {x: ref xf, ..}] => println!("{}", xf),
             //[mir]~^ ERROR cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
             // No errors in AST
             _ => panic!("other case")
         }
+        drop(x);
     }
     // Field from upvar
     {
@@ -281,13 +299,15 @@ fn main() {
     }
     // Field from upvar nested
     {
+        // FIXME(#49824) -- the free region error below should probably not be there
         let mut x = 0;
            || {
-               || {
-                let y = &mut x;
-                &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
-                        //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
-                *y = 1;
+               || { //[mir]~ ERROR free region `` does not outlive
+                   let y = &mut x;
+                   &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
+                   //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
+                   *y = 1;
+                   drop(y);
                 }
            };
     }
diff --git a/src/test/compile-fail/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs b/src/test/compile-fail/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs
index f09a0c7414b..6f0e0f43f60 100644
--- a/src/test/compile-fail/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs
+++ b/src/test/compile-fail/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs
@@ -13,10 +13,12 @@
 
 fn main() {
     let mut _a = 3;
-    let _b = &mut _a;
+    let b = &mut _a;
     {
-        let _c = &*_b;
+        let c = &*b;
         _a = 4; //[ast]~ ERROR cannot assign to `_a`
-                //[mir]~^ ERROR cannot assign to `_a` because it is borrowed
+        //[mir]~^ ERROR cannot assign to `_a` because it is borrowed
+        drop(c);
     }
+    drop(b);
 }
diff --git a/src/test/compile-fail/borrowck/borrowck-lend-flow-match.rs b/src/test/compile-fail/borrowck/borrowck-lend-flow-match.rs
index 2fe764568bc..f2f3e791422 100644
--- a/src/test/compile-fail/borrowck/borrowck-lend-flow-match.rs
+++ b/src/test/compile-fail/borrowck/borrowck-lend-flow-match.rs
@@ -24,9 +24,10 @@ fn separate_arms() {
             // fact no outstanding loan of x!
             x = Some(0);
         }
-        Some(ref __isize) => {
+        Some(ref r) => {
             x = Some(1); //[ast]~ ERROR cannot assign
-                         //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+            //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+            drop(r);
         }
     }
     x.clone(); // just to prevent liveness warnings
diff --git a/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs b/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs
index 3e57ac0ca19..c2136e62a7b 100644
--- a/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs
+++ b/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs
@@ -25,16 +25,18 @@ fn match_enum() {
         Foo::A(x) => x //[ast]~ ERROR [E0503]
                        //[mir]~^ ERROR [E0503]
     };
+    drop(p);
 }
 
 
 fn main() {
     let mut x = 1;
-    let _x = &mut x;
+    let r = &mut x;
     let _ = match x { //[mir]~ ERROR [E0503]
         x => x + 1, //[ast]~ ERROR [E0503]
                     //[mir]~^ ERROR [E0503]
         y => y + 2, //[ast]~ ERROR [E0503]
                     //[mir]~^ ERROR [E0503]
     };
+    drop(r);
 }
diff --git a/src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs b/src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs
index 63bb04a0e4c..7b0a71815a5 100644
--- a/src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs
+++ b/src/test/compile-fail/borrowck/borrowck-mut-borrow-linear-errors.rs
@@ -17,14 +17,14 @@
 
 fn main() {
     let mut x = 1;
-    let mut addr;
+    let mut addr = vec![];
     loop {
         match 1 {
-            1 => { addr = &mut x; } //[ast]~ ERROR [E0499]
+            1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
             //[mir]~^ ERROR [E0499]
-            2 => { addr = &mut x; } //[ast]~ ERROR [E0499]
+            2 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
             //[mir]~^ ERROR [E0499]
-            _ => { addr = &mut x; } //[ast]~ ERROR [E0499]
+            _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
             //[mir]~^ ERROR [E0499]
         }
     }
diff --git a/src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs b/src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs
index 3a4c22eb139..109fe3d1128 100644
--- a/src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs
+++ b/src/test/compile-fail/borrowck/borrowck-overloaded-index-ref-index.rs
@@ -71,4 +71,5 @@ fn main() {
     s[2] = 20;
     //[ast]~^ ERROR cannot assign to immutable indexed content
     //[mir]~^^ ERROR cannot assign to immutable item
+    drop(rs);
 }
diff --git a/src/test/compile-fail/borrowck/borrowck-pat-reassign-binding.rs b/src/test/compile-fail/borrowck/borrowck-pat-reassign-binding.rs
index 0f3a8418210..d917a0abb88 100644
--- a/src/test/compile-fail/borrowck/borrowck-pat-reassign-binding.rs
+++ b/src/test/compile-fail/borrowck/borrowck-pat-reassign-binding.rs
@@ -21,7 +21,8 @@ fn main() {
       Some(ref i) => {
           // But on this branch, `i` is an outstanding borrow
           x = Some(*i+1); //[ast]~ ERROR cannot assign to `x`
-                          //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+          //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+          drop(i);
       }
     }
     x.clone(); // just to prevent liveness warnings
diff --git a/src/test/compile-fail/borrowck/borrowck-union-borrow.rs b/src/test/compile-fail/borrowck/borrowck-union-borrow.rs
index 0241b3870c7..97193bd0191 100644
--- a/src/test/compile-fail/borrowck/borrowck-union-borrow.rs
+++ b/src/test/compile-fail/borrowck/borrowck-union-borrow.rs
@@ -25,82 +25,98 @@ fn main() {
         {
             let ra = &u.a;
             let ra2 = &u.a; // OK
+            drop(ra);
         }
         {
             let ra = &u.a;
             let a = u.a; // OK
+            drop(ra);
         }
         {
             let ra = &u.a;
             let rma = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
                                 //[mir]~^ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
+            drop(ra);
         }
         {
             let ra = &u.a;
             u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
                      //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
+            drop(ra);
         }
         // Imm borrow, other field
         {
             let ra = &u.a;
             let rb = &u.b; // OK
+            drop(ra);
         }
         {
             let ra = &u.a;
             let b = u.b; // OK
+            drop(ra);
         }
         {
             let ra = &u.a;
             let rmb = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
                                 //[mir]~^ ERROR cannot borrow `u.b` as mutable because it is also borrowed as immutable
+            drop(ra);
         }
         {
             let ra = &u.a;
             u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
                      //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
+            drop(ra);
         }
         // Mut borrow, same field
         {
             let rma = &mut u.a;
             let ra = &u.a; //[ast]~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
                          //[mir]~^ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
+            drop(rma);
         }
         {
             let ra = &mut u.a;
             let a = u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
                          //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
+            drop(ra);
         }
         {
             let rma = &mut u.a;
             let rma2 = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable more than once at a time
                                  //[mir]~^ ERROR cannot borrow `u.a` as mutable more than once at a time
+            drop(rma);
         }
         {
             let rma = &mut u.a;
             u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
                      //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
+            drop(rma);
         }
         // Mut borrow, other field
         {
             let rma = &mut u.a;
             let rb = &u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
                            //[mir]~^ ERROR cannot borrow `u.b` as immutable because it is also borrowed as mutable
+            drop(rma);
         }
         {
             let ra = &mut u.a;
             let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed
                          //[mir]~^ ERROR cannot use `u.b` because it was mutably borrowed
 
+            drop(ra);
         }
         {
             let rma = &mut u.a;
             let rmb2 = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
                                  //[mir]~^ ERROR cannot borrow `u.b` as mutable more than once at a time
+            drop(rma);
         }
         {
             let rma = &mut u.a;
             u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
                      //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
+            drop(rma);
         }
     }
 }
diff --git a/src/test/compile-fail/borrowck/two-phase-across-loop.rs b/src/test/compile-fail/borrowck/two-phase-across-loop.rs
new file mode 100644
index 00000000000..e03a0355b48
--- /dev/null
+++ b/src/test/compile-fail/borrowck/two-phase-across-loop.rs
@@ -0,0 +1,34 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that a borrow which starts as a 2-phase borrow and gets
+// carried around a loop winds up conflicting with itself.
+
+#![feature(nll)]
+
+struct Foo { x: String }
+
+impl Foo {
+    fn get_string(&mut self) -> &str {
+        &self.x
+    }
+}
+
+fn main() {
+    let mut foo = Foo { x: format!("Hello, world") };
+    let mut strings = vec![];
+
+    loop {
+        strings.push(foo.get_string()); //~ ERROR cannot borrow `foo` as mutable
+        if strings.len() > 2 { break; }
+    }
+
+    println!("{:?}", strings);
+}
diff --git a/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs
index 90933c6b31f..77b237e34f2 100644
--- a/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs
+++ b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs
@@ -13,10 +13,9 @@
 // revisions: nll_target
 
 // The following revisions are disabled due to missing support from two-phase beyond autorefs
-//[lxl_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref
-//[nll_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref -Z nll
+//[nll_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref
 
-//[nll_target] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+//[nll_target] compile-flags: -Z borrowck=mir -Z two-phase-borrows
 
 // This is an important corner case pointed out by Niko: one is
 // allowed to initiate a shared borrow during a reservation, but it
diff --git a/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs b/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs
index d2f4154433a..5deabf93764 100644
--- a/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs
+++ b/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs
@@ -13,11 +13,9 @@
 // revisions: nll_target
 
 // The following revisions are disabled due to missing support for two_phase_beyond_autoref
-//[lxl_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two_phase_beyond_autoref
-//[nll_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two_phase_beyond_autoref -Z nll
+//[nll_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two_phase_beyond_autoref
 
-
-//[nll_target] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+//[nll_target] compile-flags: -Z borrowck=mir -Z two-phase-borrows
 
 // This is the second counter-example from Niko's blog post
 // smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/
@@ -44,9 +42,8 @@ fn main() {
 
     /*3*/ *p += 1;        // (mutable borrow of `i` starts here, since `p` is used)
 
-    /*4*/ let k = i;      //[lxl_beyond]~   ERROR cannot use `i` because it was mutably borrowed [E0503]
-                          //[nll_beyond]~^  ERROR cannot use `i` because it was mutably borrowed [E0503]
-                          //[nll_target]~^^ ERROR cannot use `i` because it was mutably borrowed [E0503]
+    /*4*/ let k = i;      //[nll_beyond]~  ERROR cannot use `i` because it was mutably borrowed [E0503]
+                          //[nll_target]~^ ERROR cannot use `i` because it was mutably borrowed [E0503]
 
     /*5*/ *p += 1;
 
diff --git a/src/test/compile-fail/borrowck/two-phase-cannot-nest-mut-self-calls.rs b/src/test/compile-fail/borrowck/two-phase-cannot-nest-mut-self-calls.rs
index 01b04708599..15700a1d61a 100644
--- a/src/test/compile-fail/borrowck/two-phase-cannot-nest-mut-self-calls.rs
+++ b/src/test/compile-fail/borrowck/two-phase-cannot-nest-mut-self-calls.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// revisions: lxl nll
-//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
-//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+// compile-flags: -Z borrowck=mir -Z two-phase-borrows
 
 // This is the third counter-example from Niko's blog post
 // smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/
@@ -26,8 +24,7 @@ fn main() {
     vec.get({
 
         vec.push(2);
-        //[lxl]~^ ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable
-        //[nll]~^^   ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable
+        //~^ ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable
 
         0
     });
diff --git a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs
index ef39fabda10..4303048138d 100644
--- a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs
+++ b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// revisions: ast lxl nll
+// revisions: ast nll
 //[ast]compile-flags:
-//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
-//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows
 
-//[g2p]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll -Z two-phase-beyond-autoref
+//[g2p]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref
 // the above revision is disabled until two-phase-beyond-autoref support is better
 
 // This is a test checking that when we limit two-phase borrows to
@@ -69,44 +68,38 @@ fn overloaded_call_traits() {
 
     fn twice_ten_sm<F: FnMut(i32) -> i32>(f: &mut F) {
         f(f(10));
-        //[lxl]~^     ERROR cannot borrow `*f` as mutable more than once at a time
-        //[nll]~^^   ERROR cannot borrow `*f` as mutable more than once at a time
-        //[g2p]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time
-        //[ast]~^^^^ ERROR cannot borrow `*f` as mutable more than once at a time
+        //[nll]~^   ERROR cannot borrow `*f` as mutable more than once at a time
+        //[g2p]~^^ ERROR cannot borrow `*f` as mutable more than once at a time
+        //[ast]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time
     }
     fn twice_ten_si<F: Fn(i32) -> i32>(f: &mut F) {
         f(f(10));
     }
     fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) {
         f(f(10));
-        //[lxl]~^    ERROR use of moved value: `*f`
-        //[nll]~^^   ERROR use of moved value: `*f`
-        //[g2p]~^^^  ERROR use of moved value: `*f`
-        //[ast]~^^^^ ERROR use of moved value: `*f`
+        //[nll]~^   ERROR use of moved value: `*f`
+        //[g2p]~^^  ERROR use of moved value: `*f`
+        //[ast]~^^^ ERROR use of moved value: `*f`
     }
 
     fn twice_ten_om(f: &mut FnMut(i32) -> i32) {
         f(f(10));
-        //[lxl]~^    ERROR cannot borrow `*f` as mutable more than once at a time
-        //[nll]~^^   ERROR cannot borrow `*f` as mutable more than once at a time
-        //[g2p]~^^^  ERROR cannot borrow `*f` as mutable more than once at a time
-        //[ast]~^^^^ ERROR cannot borrow `*f` as mutable more than once at a time
+        //[nll]~^   ERROR cannot borrow `*f` as mutable more than once at a time
+        //[g2p]~^^  ERROR cannot borrow `*f` as mutable more than once at a time
+        //[ast]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time
     }
     fn twice_ten_oi(f: &mut Fn(i32) -> i32) {
         f(f(10));
     }
     fn twice_ten_oo(f: Box<FnOnce(i32) -> i32>) {
         f(f(10));
-        //[lxl]~^             ERROR cannot move a value of type
-        //[lxl]~^^            ERROR cannot move a value of type
-        //[lxl]~^^^           ERROR use of moved value: `*f`
-        //[nll]~^^^^          ERROR cannot move a value of type
-        //[nll]~^^^^^         ERROR cannot move a value of type
-        //[nll]~^^^^^^        ERROR use of moved value: `*f`
-        //[g2p]~^^^^^^^       ERROR cannot move a value of type
-        //[g2p]~^^^^^^^^      ERROR cannot move a value of type
-        //[g2p]~^^^^^^^^^     ERROR use of moved value: `*f`
-        //[ast]~^^^^^^^^^^    ERROR use of moved value: `*f`
+        //[nll]~^          ERROR cannot move a value of type
+        //[nll]~^^         ERROR cannot move a value of type
+        //[nll]~^^^        ERROR use of moved value: `*f`
+        //[g2p]~^^^^       ERROR cannot move a value of type
+        //[g2p]~^^^^^      ERROR cannot move a value of type
+        //[g2p]~^^^^^^     ERROR use of moved value: `*f`
+        //[ast]~^^^^^^^    ERROR use of moved value: `*f`
     }
 
     twice_ten_sm(&mut |x| x + 1);
@@ -144,10 +137,9 @@ fn coerce_unsized() {
 
     // This is not okay.
     double_access(&mut a, &a);
-    //[lxl]~^    ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
-    //[nll]~^^   ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
-    //[g2p]~^^^  ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
-    //[ast]~^^^^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
+    //[nll]~^   ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
+    //[g2p]~^^  ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
+    //[ast]~^^^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502]
 
     // But this is okay.
     a.m(a.i(10));
@@ -173,16 +165,14 @@ impl IndexMut<i32> for I {
 fn coerce_index_op() {
     let mut i = I(10);
     i[i[3]] = 4;
-    //[lxl]~^   ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
-    //[nll]~^^  ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
-    //[ast]~^^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[nll]~^  ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[ast]~^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
 
     i[3] = i[4];
 
     i[i[3]] = i[4];
-    //[lxl]~^   ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
-    //[nll]~^^  ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
-    //[ast]~^^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[nll]~^  ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
+    //[ast]~^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502]
 }
 
 fn main() {
diff --git a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs b/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs
index fc9100c8a9a..f9326d944b8 100644
--- a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs
+++ b/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// revisions: lxl nll
-//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
-//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+// compile-flags: -Z borrowck=mir -Z two-phase-borrows
 
 // This is similar to two-phase-reservation-sharing-interference.rs
 // in that it shows a reservation that overlaps with a shared borrow.
@@ -26,12 +24,11 @@
 #![feature(rustc_attrs)]
 
 #[rustc_error]
-fn main() { //[nll]~ ERROR compilation successful
+fn main() { //~ ERROR compilation successful
     let mut v = vec![0, 1, 2];
     let shared = &v;
 
     v.push(shared.len());
-    //[lxl]~^  ERROR cannot borrow `v` as mutable because it is also borrowed as immutable [E0502]
 
     assert_eq!(v, [0, 1, 2, 3]);
 }
diff --git a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference.rs b/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference.rs
index 058022ad588..1333167b780 100644
--- a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference.rs
+++ b/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference.rs
@@ -10,15 +10,13 @@
 
 // ignore-tidy-linelength
 
-// revisions: lxl_beyond nll_beyond nll_target
+// revisions: nll_beyond nll_target
 
 // The following revisions are disabled due to missing support from two-phase beyond autorefs
-//[lxl_beyond]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref
-//[lxl_beyond] should-fail
-//[nll_beyond]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref -Z nll
+//[nll_beyond]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref
 //[nll_beyond] should-fail
 
-//[nll_target]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+//[nll_target]compile-flags: -Z borrowck=mir -Z two-phase-borrows
 
 // This is a corner case that the current implementation is (probably)
 // treating more conservatively than is necessary. But it also does
@@ -46,9 +44,8 @@ fn main() {
         // with the shared borrow. But in the current implementation,
         // its an error.
         delay = &mut vec;
-        //[lxl_beyond]~^   ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable
-        //[nll_beyond]~^^  ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable
-        //[nll_target]~^^^ ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable
+        //[nll_beyond]~^  ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable
+        //[nll_target]~^^ ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable
 
         shared[0];
     }
diff --git a/src/test/compile-fail/borrowck/two-phase-sneaky.rs b/src/test/compile-fail/borrowck/two-phase-sneaky.rs
index 32747407c67..eec4b470d75 100644
--- a/src/test/compile-fail/borrowck/two-phase-sneaky.rs
+++ b/src/test/compile-fail/borrowck/two-phase-sneaky.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// revisions: lxl nll
-//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
-//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+// cmpile-flags: -Z borrowck=mir -Z two-phase-borrows
 
 // This is the first counter-example from Niko's blog post
 // smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/
@@ -22,8 +20,7 @@ fn main() {
     v[0].push_str({
 
         v.push(format!("foo"));
-        //[lxl]~^ ERROR cannot borrow `v` as mutable more than once at a time [E0499]
-        //[nll]~^^   ERROR cannot borrow `v` as mutable more than once at a time [E0499]
+        //~^   ERROR cannot borrow `v` as mutable more than once at a time [E0499]
 
         "World!"
     });
diff --git a/src/test/compile-fail/coerce-overloaded-autoderef.rs b/src/test/compile-fail/coerce-overloaded-autoderef.rs
index 0487b03171a..5a05f59c6f4 100644
--- a/src/test/compile-fail/coerce-overloaded-autoderef.rs
+++ b/src/test/compile-fail/coerce-overloaded-autoderef.rs
@@ -22,6 +22,7 @@ fn double_mut_borrow<T>(x: &mut Box<T>) {
     let z = borrow_mut(x);
     //[ast]~^ ERROR cannot borrow `*x` as mutable more than once at a time
     //[mir]~^^ ERROR cannot borrow `*x` as mutable more than once at a time
+    drop((y, z));
 }
 
 fn double_imm_borrow(x: &mut Box<i32>) {
@@ -30,6 +31,7 @@ fn double_imm_borrow(x: &mut Box<i32>) {
     **x += 1;
     //[ast]~^ ERROR cannot assign to `**x` because it is borrowed
     //[mir]~^^ ERROR cannot assign to `**x` because it is borrowed
+    drop((y, z));
 }
 
 fn double_mut_borrow2<T>(x: &mut Box<T>) {
diff --git a/src/test/compile-fail/hrtb-identity-fn-borrows.rs b/src/test/compile-fail/hrtb-identity-fn-borrows.rs
index 5f5b70dda5e..e98cf4eb2ab 100644
--- a/src/test/compile-fail/hrtb-identity-fn-borrows.rs
+++ b/src/test/compile-fail/hrtb-identity-fn-borrows.rs
@@ -33,6 +33,7 @@ fn call_repeatedly<F>(f: F)
     f.call(&x);
     f.call(&x);
     x = 5;
+    drop(y);
 }
 
 fn main() {
diff --git a/src/test/compile-fail/issue-36082.rs b/src/test/compile-fail/issue-36082.rs
index fc3e0633750..ed6a2f85fbe 100644
--- a/src/test/compile-fail/issue-36082.rs
+++ b/src/test/compile-fail/issue-36082.rs
@@ -11,6 +11,8 @@
 // revisions: ast mir
 //[mir]compile-flags: -Z borrowck=mir
 
+// FIXME(#49821) -- No tip about using a let binding
+
 use std::cell::RefCell;
 
 fn main() {
@@ -24,10 +26,9 @@ fn main() {
     //[ast]~| NOTE temporary value does not live long enough
     //[ast]~| NOTE consider using a `let` binding to increase its lifetime
     //[mir]~^^^^^ ERROR borrowed value does not live long enough [E0597]
-    //[mir]~| NOTE temporary value dropped here while still borrowed
     //[mir]~| NOTE temporary value does not live long enough
-    //[mir]~| NOTE consider using a `let` binding to increase its lifetime
+    //[mir]~| NOTE temporary value only lives until here
     println!("{}", val);
+    //[mir]~^ borrow later used here
 }
 //[ast]~^ NOTE temporary value needs to live until here
-//[mir]~^^ NOTE temporary value needs to live until here
diff --git a/src/test/compile-fail/mir_check_cast_closure.rs b/src/test/compile-fail/mir_check_cast_closure.rs
index 6562efeb6d8..d8f5956b585 100644
--- a/src/test/compile-fail/mir_check_cast_closure.rs
+++ b/src/test/compile-fail/mir_check_cast_closure.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z borrowck=mir -Z nll
+// compile-flags: -Z borrowck=mir
 
 #![allow(dead_code)]
 
@@ -16,7 +16,7 @@ fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 {
     let g: fn(_, _) -> _ = |_x, y| y;
     //~^ ERROR free region `'b` does not outlive free region `'a`
     g
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/mir_check_cast_reify.rs b/src/test/compile-fail/mir_check_cast_reify.rs
index f6ad2820d17..1f9174b3574 100644
--- a/src/test/compile-fail/mir_check_cast_reify.rs
+++ b/src/test/compile-fail/mir_check_cast_reify.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z borrowck=mir -Z nll
+// compile-flags: -Zborrowck=mir
 
 #![allow(dead_code)]
 
@@ -44,7 +44,7 @@ fn bar<'a>(x: &'a u32) -> &'static u32 {
     // The MIR type checker must therefore relate `'?0` to `'?1` and `'?2`
     // as part of checking the `ReifyFnPointer`.
     let f: fn(_) -> _ = foo;
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR free region `'a` does not outlive free region `'static`
     f(x)
 }
diff --git a/src/test/compile-fail/mir_check_cast_unsafe_fn.rs b/src/test/compile-fail/mir_check_cast_unsafe_fn.rs
index c9b378dacd5..27ca2728ddf 100644
--- a/src/test/compile-fail/mir_check_cast_unsafe_fn.rs
+++ b/src/test/compile-fail/mir_check_cast_unsafe_fn.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z borrowck=mir -Z nll
+// compile-flags: -Zborrowck=mir
 
 #![allow(dead_code)]
 
@@ -16,7 +16,7 @@ fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
     // Here the NLL checker must relate the types in `f` to the types
     // in `g`. These are related via the `UnsafeFnPointer` cast.
     let g: unsafe fn(_) -> _ = f;
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR free region `'a` does not outlive free region `'static`
     unsafe { g(input) }
 }
diff --git a/src/test/compile-fail/mir_check_cast_unsize.rs b/src/test/compile-fail/mir_check_cast_unsize.rs
index 1df56793f73..e30bed61058 100644
--- a/src/test/compile-fail/mir_check_cast_unsize.rs
+++ b/src/test/compile-fail/mir_check_cast_unsize.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z borrowck=mir -Z nll
+// compile-flags: -Z borrowck=mir
 
 #![allow(dead_code)]
 #![feature(dyn_trait)]
@@ -18,7 +18,7 @@ use std::fmt::Debug;
 fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
     //~^ ERROR free region `'a` does not outlive free region `'static`
     x
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/mut-pattern-internal-mutability.rs b/src/test/compile-fail/mut-pattern-internal-mutability.rs
index 72727cdfe54..a05ee64937e 100644
--- a/src/test/compile-fail/mut-pattern-internal-mutability.rs
+++ b/src/test/compile-fail/mut-pattern-internal-mutability.rs
@@ -25,5 +25,6 @@ fn main() {
     // check borrowing is detected successfully
     let &mut ref x = foo;
     *foo += 1; //[ast]~ ERROR cannot assign to `*foo` because it is borrowed
-               //[mir]~^ ERROR cannot assign to `*foo` because it is borrowed
+    //[mir]~^ ERROR cannot assign to `*foo` because it is borrowed
+    drop(x);
 }
diff --git a/src/test/compile-fail/nll/loan_ends_mid_block_pair.rs b/src/test/compile-fail/nll/loan_ends_mid_block_pair.rs
index fdc650a0721..97126e98cbf 100644
--- a/src/test/compile-fail/nll/loan_ends_mid_block_pair.rs
+++ b/src/test/compile-fail/nll/loan_ends_mid_block_pair.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-// compile-flags:-Zborrowck=compare -Znll
+// compile-flags:-Zborrowck=compare
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
diff --git a/src/test/compile-fail/nll/loan_ends_mid_block_vec.rs b/src/test/compile-fail/nll/loan_ends_mid_block_vec.rs
index f22d2fc23e0..b5357d0ee82 100644
--- a/src/test/compile-fail/nll/loan_ends_mid_block_vec.rs
+++ b/src/test/compile-fail/nll/loan_ends_mid_block_vec.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-// compile-flags:-Zborrowck=compare -Znll
+// compile-flags:-Zborrowck=compare
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
diff --git a/src/test/compile-fail/nll/reference-carried-through-struct-field.rs b/src/test/compile-fail/nll/reference-carried-through-struct-field.rs
index efa6cc273b6..589a3daa38d 100644
--- a/src/test/compile-fail/nll/reference-carried-through-struct-field.rs
+++ b/src/test/compile-fail/nll/reference-carried-through-struct-field.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 //revisions: ast mir
-//[mir] compile-flags: -Z borrowck=mir -Z nll
+//[mir] compile-flags: -Z borrowck=mir
 
 #![allow(unused_assignments)]
 
diff --git a/src/test/compile-fail/nll/region-ends-after-if-condition.rs b/src/test/compile-fail/nll/region-ends-after-if-condition.rs
index 1128d65af95..e1c47a6bbff 100644
--- a/src/test/compile-fail/nll/region-ends-after-if-condition.rs
+++ b/src/test/compile-fail/nll/region-ends-after-if-condition.rs
@@ -12,7 +12,7 @@
 // in the type of `p` includes the points after `&v[0]` up to (but not
 // including) the call to `use_x`. The `else` branch is not included.
 
-// compile-flags:-Zborrowck=compare -Znll
+// compile-flags:-Zborrowck=compare
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
diff --git a/src/test/compile-fail/nll/return_from_loop.rs b/src/test/compile-fail/nll/return_from_loop.rs
index 7ed59ef2a87..13f1ca6431b 100644
--- a/src/test/compile-fail/nll/return_from_loop.rs
+++ b/src/test/compile-fail/nll/return_from_loop.rs
@@ -12,7 +12,7 @@
 // in the type of `p` includes the points after `&v[0]` up to (but not
 // including) the call to `use_x`. The `else` branch is not included.
 
-// compile-flags:-Zborrowck=compare -Znll
+// compile-flags:-Zborrowck=compare
 
 #![allow(warnings)]
 #![feature(rustc_attrs)]
diff --git a/src/test/compile-fail/nll/where_clauses_in_functions.rs b/src/test/compile-fail/nll/where_clauses_in_functions.rs
index ecea8756903..1a3dc76005d 100644
--- a/src/test/compile-fail/nll/where_clauses_in_functions.rs
+++ b/src/test/compile-fail/nll/where_clauses_in_functions.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z borrowck=mir -Z nll
+// compile-flags: -Zborrowck=mir
 
 #![allow(dead_code)]
 
@@ -22,7 +22,7 @@ where
 fn bar<'a, 'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
     foo(x, y)
     //~^ ERROR lifetime mismatch [E0623]
-    //~| WARNING not reporting region error due to -Znll
+    //~| WARNING not reporting region error due to nll
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/nll/where_clauses_in_structs.rs b/src/test/compile-fail/nll/where_clauses_in_structs.rs
index f1a6dc48e13..69f0f43af13 100644
--- a/src/test/compile-fail/nll/where_clauses_in_structs.rs
+++ b/src/test/compile-fail/nll/where_clauses_in_structs.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z borrowck=mir -Z nll
+// compile-flags: -Z borrowck=mir
 
 #![allow(dead_code)]
 
@@ -22,7 +22,7 @@ struct Foo<'a: 'b, 'b> {
 fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) {
     Foo { x, y };
     //~^ ERROR lifetime mismatch [E0623]
-    //~| WARNING not reporting region error due to -Znll
+    //~| WARNING not reporting region error due to nll
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/regions-pattern-typing-issue-19997.rs b/src/test/compile-fail/regions-pattern-typing-issue-19997.rs
index 6fbc65ce6a7..1f23dcbb725 100644
--- a/src/test/compile-fail/regions-pattern-typing-issue-19997.rs
+++ b/src/test/compile-fail/regions-pattern-typing-issue-19997.rs
@@ -18,7 +18,8 @@ fn main() {
     match (&a1,) {
         (&ref b0,) => {
             a1 = &f; //[ast]~ ERROR cannot assign
-                     //[mir]~^ ERROR cannot assign to `a1` because it is borrowed
+            //[mir]~^ ERROR cannot assign to `a1` because it is borrowed
+            drop(b0);
         }
     }
 }
diff --git a/src/test/compile-fail/regions-static-bound.rs b/src/test/compile-fail/regions-static-bound.rs
index 13f93090fbb..a0097b9f6d7 100644
--- a/src/test/compile-fail/regions-static-bound.rs
+++ b/src/test/compile-fail/regions-static-bound.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // revisions: ll nll
-//[nll] compile-flags: -Znll -Zborrowck=mir
+//[nll] compile-flags:-Zborrowck=mir
 
 fn static_id<'a,'b>(t: &'a ()) -> &'static ()
     where 'a: 'static { t }
@@ -17,16 +17,16 @@ fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
     where 'a: 'b, 'b: 'static { t }
 fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
     t //[ll]~ ERROR E0312
-        //[nll]~^ WARNING not reporting region error due to -Znll
+        //[nll]~^ WARNING not reporting region error due to nll
         //[nll]~| ERROR free region `'a` does not outlive free region `'static`
 }
 
 fn error(u: &(), v: &()) {
     static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
-    //[nll]~^ WARNING not reporting region error due to -Znll
+    //[nll]~^ WARNING not reporting region error due to nll
     //[nll]~| ERROR explicit lifetime required in the type of `u` [E0621]
     static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
-    //[nll]~^ WARNING not reporting region error due to -Znll
+    //[nll]~^ WARNING not reporting region error due to nll
     //[nll]~| ERROR explicit lifetime required in the type of `v` [E0621]
 }
 
diff --git a/src/test/mir-opt/nll/liveness-call-subtlety.rs b/src/test/mir-opt/nll/liveness-call-subtlety.rs
index 09288cf69ff..f41b39845a5 100644
--- a/src/test/mir-opt/nll/liveness-call-subtlety.rs
+++ b/src/test/mir-opt/nll/liveness-call-subtlety.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll
+// compile-flags:-Zborrowck=mir
 
 fn can_panic() -> Box<usize> {
     Box::new(44)
diff --git a/src/test/mir-opt/nll/liveness-drop-intra-block.rs b/src/test/mir-opt/nll/liveness-drop-intra-block.rs
index 64ffc744606..073b44d6e33 100644
--- a/src/test/mir-opt/nll/liveness-drop-intra-block.rs
+++ b/src/test/mir-opt/nll/liveness-drop-intra-block.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll
+// compile-flags:-Zborrowck=mir
 
 #![allow(warnings)]
 
diff --git a/src/test/mir-opt/nll/liveness-interblock.rs b/src/test/mir-opt/nll/liveness-interblock.rs
index 671f5e5292a..6a874908406 100644
--- a/src/test/mir-opt/nll/liveness-interblock.rs
+++ b/src/test/mir-opt/nll/liveness-interblock.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll
+// compile-flags:-Zborrowck=mir
 
 fn cond() -> bool { false }
 
diff --git a/src/test/mir-opt/nll/named-lifetimes-basic.rs b/src/test/mir-opt/nll/named-lifetimes-basic.rs
index 8feac15d69a..5cca3e55259 100644
--- a/src/test/mir-opt/nll/named-lifetimes-basic.rs
+++ b/src/test/mir-opt/nll/named-lifetimes-basic.rs
@@ -13,8 +13,8 @@
 // suitable variables and that we setup the outlives relationship
 // between R0 and R1 properly.
 
-// compile-flags:-Znll -Zverbose
-//                     ^^^^^^^^^ force compiler to dump more region information
+// compile-flags:-Zborrowck=mir -Zverbose
+//                              ^^^^^^^^^ force compiler to dump more region information
 // ignore-tidy-linelength
 
 #![allow(warnings)]
diff --git a/src/test/mir-opt/nll/reborrow-basic.rs b/src/test/mir-opt/nll/reborrow-basic.rs
index 92e42a73bbb..b7c8d81b77f 100644
--- a/src/test/mir-opt/nll/reborrow-basic.rs
+++ b/src/test/mir-opt/nll/reborrow-basic.rs
@@ -12,8 +12,8 @@
 // in the type of `r_a` must outlive the region (`R7`) that appears in
 // the type of `r_b`
 
-// compile-flags:-Znll -Zverbose
-//                     ^^^^^^^^^ force compiler to dump more region information
+// compile-flags:-Zborrowck=mir -Zverbose
+//                              ^^^^^^^^^ force compiler to dump more region information
 
 #![allow(warnings)]
 
diff --git a/src/test/mir-opt/nll/region-liveness-basic.rs b/src/test/mir-opt/nll/region-liveness-basic.rs
index 19d733d4f6b..75d8a6a4f6a 100644
--- a/src/test/mir-opt/nll/region-liveness-basic.rs
+++ b/src/test/mir-opt/nll/region-liveness-basic.rs
@@ -12,8 +12,8 @@
 // in the type of `p` includes the points after `&v[0]` up to (but not
 // including) the call to `use_x`. The `else` branch is not included.
 
-// compile-flags:-Znll -Zverbose
-//                     ^^^^^^^^^ force compiler to dump more region information
+// compile-flags:-Zborrowck=mir -Zverbose
+//                              ^^^^^^^^^ force compiler to dump more region information
 
 #![allow(warnings)]
 
diff --git a/src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs b/src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs
index 821cd736671..153739133ac 100644
--- a/src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs
+++ b/src/test/mir-opt/nll/region-liveness-two-disjoint-uses.rs
@@ -14,8 +14,8 @@
 // but only at a particular point, and hence they wind up including
 // distinct regions.
 
-// compile-flags:-Znll -Zverbose
-//                     ^^^^^^^^^ force compiler to dump more region information
+// compile-flags:-Zborrowck=mir -Zverbose
+//                              ^^^^^^^^^ force compiler to dump more region information
 
 #![allow(warnings)]
 
diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region-subtyping-basic.rs
index a3f68ed5ebf..16952143d0a 100644
--- a/src/test/mir-opt/nll/region-subtyping-basic.rs
+++ b/src/test/mir-opt/nll/region-subtyping-basic.rs
@@ -12,8 +12,8 @@
 // in the type of `p` includes the points after `&v[0]` up to (but not
 // including) the call to `use_x`. The `else` branch is not included.
 
-// compile-flags:-Znll -Zverbose
-//                     ^^^^^^^^^ force compiler to dump more region information
+// compile-flags:-Zborrowck=mir -Zverbose
+//                              ^^^^^^^^^ force compiler to dump more region information
 
 #![allow(warnings)]
 
diff --git a/src/test/run-pass/borrowck/two-phase-baseline.rs b/src/test/run-pass/borrowck/two-phase-baseline.rs
index 66234449263..ca15591a101 100644
--- a/src/test/run-pass/borrowck/two-phase-baseline.rs
+++ b/src/test/run-pass/borrowck/two-phase-baseline.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// revisions: lxl nll
-//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
-//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+// compile-flags: -Z borrowck=mir -Z two-phase-borrows
 
 // This is the "goto example" for why we want two phase borrows.
 
diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs
index b1db2030717..e3b7322e48b 100644
--- a/src/test/run-pass/impl-trait/example-calendar.rs
+++ b/src/test/run-pass/impl-trait/example-calendar.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // revisions: normal nll
-//[nll] compile-flags: -Znll -Zborrowck=mir
+//[nll] compile-flags:-Zborrowck=mir
 
 #![feature(fn_traits,
            step_trait,
diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut.rs b/src/test/ui/borrowck/borrowck-closures-two-mut.rs
index b6946154fa0..55e73af9e6a 100644
--- a/src/test/ui/borrowck/borrowck-closures-two-mut.rs
+++ b/src/test/ui/borrowck/borrowck-closures-two-mut.rs
@@ -23,6 +23,7 @@ fn a() {
     let c1 = to_fn_mut(|| x = 4);
     let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable more than once
     //~| ERROR cannot borrow `x` as mutable more than once
+    drop((c1, c2));
 }
 
 fn set(x: &mut isize) {
@@ -34,6 +35,7 @@ fn b() {
     let c1 = to_fn_mut(|| set(&mut x));
     let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once
     //~| ERROR cannot borrow `x` as mutable more than once
+    drop((c1, c2));
 }
 
 fn c() {
@@ -41,6 +43,7 @@ fn c() {
     let c1 = to_fn_mut(|| x = 5);
     let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once
     //~| ERROR cannot borrow `x` as mutable more than once
+    drop((c1, c2));
 }
 
 fn d() {
@@ -49,6 +52,7 @@ fn d() {
     let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure)
     //~^ ERROR cannot borrow `x` as mutable more than once
     //~| ERROR cannot borrow `x` as mutable more than once
+    drop((c1, c2));
 }
 
 fn g() {
@@ -61,6 +65,7 @@ fn g() {
     let c2 = to_fn_mut(|| set(&mut *x.f));
     //~^ ERROR cannot borrow `x` as mutable more than once
     //~| ERROR cannot borrow `x` as mutable more than once
+    drop((c1, c2));
 }
 
 fn main() {
diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr
index c739165ddbd..a4f8e8b408b 100644
--- a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr
+++ b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr
@@ -9,12 +9,12 @@ LL |     let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable mo
    |                        ^^ - borrow occurs due to use of `x` in closure
    |                        |
    |                        second mutable borrow occurs here
-LL |     //~| ERROR cannot borrow `x` as mutable more than once
+...
 LL | }
    | - first borrow ends here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast)
-  --> $DIR/borrowck-closures-two-mut.rs:35:24
+  --> $DIR/borrowck-closures-two-mut.rs:36:24
    |
 LL |     let c1 = to_fn_mut(|| set(&mut x));
    |                        --          - previous borrow occurs due to use of `x` in closure
@@ -24,12 +24,12 @@ LL |     let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as muta
    |                        ^^          - borrow occurs due to use of `x` in closure
    |                        |
    |                        second mutable borrow occurs here
-LL |     //~| ERROR cannot borrow `x` as mutable more than once
+...
 LL | }
    | - first borrow ends here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast)
-  --> $DIR/borrowck-closures-two-mut.rs:42:24
+  --> $DIR/borrowck-closures-two-mut.rs:44:24
    |
 LL |     let c1 = to_fn_mut(|| x = 5);
    |                        -- - previous borrow occurs due to use of `x` in closure
@@ -39,12 +39,12 @@ LL |     let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as muta
    |                        ^^          - borrow occurs due to use of `x` in closure
    |                        |
    |                        second mutable borrow occurs here
-LL |     //~| ERROR cannot borrow `x` as mutable more than once
+...
 LL | }
    | - first borrow ends here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast)
-  --> $DIR/borrowck-closures-two-mut.rs:49:24
+  --> $DIR/borrowck-closures-two-mut.rs:52:24
    |
 LL |     let c1 = to_fn_mut(|| x = 5);
    |                        -- - previous borrow occurs due to use of `x` in closure
@@ -59,7 +59,7 @@ LL | }
    | - first borrow ends here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast)
-  --> $DIR/borrowck-closures-two-mut.rs:61:24
+  --> $DIR/borrowck-closures-two-mut.rs:65:24
    |
 LL |     let c1 = to_fn_mut(|| set(&mut *x.f));
    |                        --           - previous borrow occurs due to use of `x` in closure
@@ -85,11 +85,11 @@ LL |     let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable mo
    |                        |
    |                        second mutable borrow occurs here
 LL |     //~| ERROR cannot borrow `x` as mutable more than once
-LL | }
-   | - first borrow ends here
+LL |     drop((c1, c2));
+   |           -- borrow later used here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
-  --> $DIR/borrowck-closures-two-mut.rs:35:24
+  --> $DIR/borrowck-closures-two-mut.rs:36:24
    |
 LL |     let c1 = to_fn_mut(|| set(&mut x));
    |                        --          - previous borrow occurs due to use of `x` in closure
@@ -100,11 +100,11 @@ LL |     let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as muta
    |                        |
    |                        second mutable borrow occurs here
 LL |     //~| ERROR cannot borrow `x` as mutable more than once
-LL | }
-   | - first borrow ends here
+LL |     drop((c1, c2));
+   |           -- borrow later used here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
-  --> $DIR/borrowck-closures-two-mut.rs:42:24
+  --> $DIR/borrowck-closures-two-mut.rs:44:24
    |
 LL |     let c1 = to_fn_mut(|| x = 5);
    |                        -- - previous borrow occurs due to use of `x` in closure
@@ -115,11 +115,11 @@ LL |     let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as muta
    |                        |
    |                        second mutable borrow occurs here
 LL |     //~| ERROR cannot borrow `x` as mutable more than once
-LL | }
-   | - first borrow ends here
+LL |     drop((c1, c2));
+   |           -- borrow later used here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
-  --> $DIR/borrowck-closures-two-mut.rs:49:24
+  --> $DIR/borrowck-closures-two-mut.rs:52:24
    |
 LL |     let c1 = to_fn_mut(|| x = 5);
    |                        -- - previous borrow occurs due to use of `x` in closure
@@ -130,11 +130,11 @@ LL |     let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nes
    |                        |
    |                        second mutable borrow occurs here
 ...
-LL | }
-   | - first borrow ends here
+LL |     drop((c1, c2));
+   |           -- borrow later used here
 
 error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir)
-  --> $DIR/borrowck-closures-two-mut.rs:61:24
+  --> $DIR/borrowck-closures-two-mut.rs:65:24
    |
 LL |     let c1 = to_fn_mut(|| set(&mut *x.f));
    |                        --           - previous borrow occurs due to use of `x` in closure
@@ -145,8 +145,8 @@ LL |     let c2 = to_fn_mut(|| set(&mut *x.f));
    |                        |
    |                        second mutable borrow occurs here
 ...
-LL | }
-   | - first borrow ends here
+LL |     drop((c1, c2));
+   |           -- borrow later used here
 
 error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/borrowck/two-phase-method-receivers.rs b/src/test/ui/borrowck/two-phase-method-receivers.rs
index e690263a916..6d7ed61bdd8 100644
--- a/src/test/ui/borrowck/two-phase-method-receivers.rs
+++ b/src/test/ui/borrowck/two-phase-method-receivers.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// revisions: lxl nll
-//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
-//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+// compile-flags: -Z borrowck=mir -Z two-phase-borrows
 
 // run-pass
 
diff --git a/src/test/ui/borrowck/two-phase-multiple-activations.rs b/src/test/ui/borrowck/two-phase-multiple-activations.rs
index e1ed41bfb2c..9ea9696511b 100644
--- a/src/test/ui/borrowck/two-phase-multiple-activations.rs
+++ b/src/test/ui/borrowck/two-phase-multiple-activations.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// revisions: lxl nll
-//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
-//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll
+// compile-flags: -Z borrowck=mir -Z two-phase-borrows
 
 // run-pass
 
diff --git a/src/test/ui/issue-45697-1.rs b/src/test/ui/issue-45697-1.rs
index 7734b14b2ab..b8be209833a 100644
--- a/src/test/ui/issue-45697-1.rs
+++ b/src/test/ui/issue-45697-1.rs
@@ -30,6 +30,7 @@ fn main() {
         *y.pointer += 1;
         //~^ ERROR cannot assign to `*y.pointer` because it is borrowed (Ast) [E0506]
         //~| ERROR cannot use `*y.pointer` because it was mutably borrowed (Mir) [E0503]
+        //~| ERROR cannot assign to `*y.pointer` because it is borrowed (Mir) [E0506]
         *z.pointer += 1;
     }
 }
diff --git a/src/test/ui/issue-45697-1.stderr b/src/test/ui/issue-45697-1.stderr
index aa899c5aee9..cf108691a0e 100644
--- a/src/test/ui/issue-45697-1.stderr
+++ b/src/test/ui/issue-45697-1.stderr
@@ -13,8 +13,22 @@ LL |         let z = copy_borrowed_ptr(&mut y);
    |                                   ------ borrow of `y` occurs here
 LL |         *y.pointer += 1;
    |         ^^^^^^^^^^^^^^^ use of borrowed `y`
+...
+LL |         *z.pointer += 1;
+   |         --------------- borrow later used here
 
-error: aborting due to 2 previous errors
+error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Mir)
+  --> $DIR/issue-45697-1.rs:30:9
+   |
+LL |         let z = copy_borrowed_ptr(&mut y);
+   |                                   ------ borrow of `*y.pointer` occurs here
+LL |         *y.pointer += 1;
+   |         ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here
+...
+LL |         *z.pointer += 1;
+   |         --------------- borrow later used here
+
+error: aborting due to 3 previous errors
 
 Some errors occurred: E0503, E0506.
 For more information about an error, try `rustc --explain E0503`.
diff --git a/src/test/ui/issue-45697.rs b/src/test/ui/issue-45697.rs
index 4e93eccd6f6..27acc2c89f7 100644
--- a/src/test/ui/issue-45697.rs
+++ b/src/test/ui/issue-45697.rs
@@ -30,6 +30,7 @@ fn main() {
         *y.pointer += 1;
         //~^ ERROR cannot assign to `*y.pointer` because it is borrowed (Ast) [E0506]
         //~| ERROR cannot use `*y.pointer` because it was mutably borrowed (Mir) [E0503]
+        //~| ERROR cannot assign to `*y.pointer` because it is borrowed (Mir) [E0506]
         *z.pointer += 1;
     }
 }
diff --git a/src/test/ui/issue-45697.stderr b/src/test/ui/issue-45697.stderr
index babfc33b945..a85972fcd7a 100644
--- a/src/test/ui/issue-45697.stderr
+++ b/src/test/ui/issue-45697.stderr
@@ -13,8 +13,22 @@ LL |         let z = copy_borrowed_ptr(&mut y);
    |                                   ------ borrow of `y` occurs here
 LL |         *y.pointer += 1;
    |         ^^^^^^^^^^^^^^^ use of borrowed `y`
+...
+LL |         *z.pointer += 1;
+   |         --------------- borrow later used here
 
-error: aborting due to 2 previous errors
+error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Mir)
+  --> $DIR/issue-45697.rs:30:9
+   |
+LL |         let z = copy_borrowed_ptr(&mut y);
+   |                                   ------ borrow of `*y.pointer` occurs here
+LL |         *y.pointer += 1;
+   |         ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here
+...
+LL |         *z.pointer += 1;
+   |         --------------- borrow later used here
+
+error: aborting due to 3 previous errors
 
 Some errors occurred: E0503, E0506.
 For more information about an error, try `rustc --explain E0503`.
diff --git a/src/test/ui/issue-46471-1.stderr b/src/test/ui/issue-46471-1.stderr
index bfd5bfa9f72..0108056bc72 100644
--- a/src/test/ui/issue-46471-1.stderr
+++ b/src/test/ui/issue-46471-1.stderr
@@ -12,13 +12,16 @@ LL | }
 error[E0597]: `z` does not live long enough (Mir)
   --> $DIR/issue-46471-1.rs:16:9
    |
-LL |         &mut z
-   |         ^^^^^^ borrowed value does not live long enough
-LL |     };
-   |     - `z` dropped here while still borrowed
-...
-LL | }
-   | - borrowed value needs to live until here
+LL |       let y = {
+   |  _____________-
+LL | |         let mut z = 0;
+LL | |         &mut z
+   | |         ^^^^^^ borrowed value does not live long enough
+LL | |     };
+   | |     -
+   | |     |
+   | |_____borrowed value only lives until here
+   |       borrow later used here
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.rs b/src/test/ui/nll/closure-requirements/escape-argument-callee.rs
index 41c744fec6e..1e168028c7c 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.rs
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.rs
@@ -22,7 +22,7 @@
 // that appear free in its type (hence, we see it before the closure's
 // "external requirements" report).
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
@@ -35,7 +35,7 @@ fn test() {
         let y = 22;
         let mut closure = expect_sig(|p, y| *p = y);
         //~^ ERROR does not outlive free region
-        //~| WARNING not reporting region error due to -Znll
+        //~| WARNING not reporting region error due to nll
         closure(&mut p, &y);
     }
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index 5f84001a8fb..d876c751a41 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/escape-argument-callee.rs:36:50
    |
 LL |         let mut closure = expect_sig(|p, y| *p = y);
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.rs b/src/test/ui/nll/closure-requirements/escape-argument.rs
index 7e918c6431d..7a28cb26f35 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.rs
+++ b/src/test/ui/nll/closure-requirements/escape-argument.rs
@@ -22,7 +22,7 @@
 // basically checking that the MIR type checker correctly enforces the
 // closure signature.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs b/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs
index 05700ae00ad..598839f872e 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs
@@ -15,7 +15,7 @@
 //
 // except that the closure does so via a second closure.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs b/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs
index 93d8bfafcba..49d31bbc139 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.rs
@@ -19,7 +19,7 @@
 // `'b`.  This relationship is propagated to the closure creator,
 // which reports an error.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
index 30a6dfc5b3e..e7ec0b9684d 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
@@ -11,7 +11,7 @@
 // Test where we fail to approximate due to demanding a postdom
 // relationship between our upper bounds.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
@@ -53,7 +53,7 @@ fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell
         |_outlives1, _outlives2, _outlives3, x, y| {
             // Only works if 'x: 'y:
             let p = x.get();
-            //~^ WARN not reporting region error due to -Znll
+            //~^ WARN not reporting region error due to nll
             //~| ERROR does not outlive free region
             demand_y(x, y, p)
         },
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index 0c058e40a50..ef5a31e40d4 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-approximated-fail-no-postdom.rs:55:21
    |
 LL |             let p = x.get();
@@ -16,7 +16,7 @@ note: No external requirements
 LL | /         |_outlives1, _outlives2, _outlives3, x, y| {
 LL | |             // Only works if 'x: 'y:
 LL | |             let p = x.get();
-LL | |             //~^ WARN not reporting region error due to -Znll
+LL | |             //~^ WARN not reporting region error due to nll
 LL | |             //~| ERROR does not outlive free region
 LL | |             demand_y(x, y, p)
 LL | |         },
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs
index 91128035f3d..da8ce55162f 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.rs
@@ -22,7 +22,7 @@
 // Note: the use of `Cell` here is to introduce invariance. One less
 // variable.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
@@ -54,7 +54,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
         //~^ ERROR lifetime mismatch
 
         // Only works if 'x: 'y:
-        demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll
+        demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
     });
 }
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
index 947b95b1c53..3a3236fd16c 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -1,7 +1,7 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-approximated-ref.rs:57:9
    |
-LL |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll
+LL |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 note: External requirements
@@ -12,7 +12,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x,
 LL | |         //~^ ERROR lifetime mismatch
 LL | |
 LL | |         // Only works if 'x: 'y:
-LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll
+LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
 LL | |     });
    | |_____^
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs
index f210346a82a..84bfd6ea4f2 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs
@@ -12,7 +12,7 @@
 // where `'x` is bound in closure type but `'a` is free. This forces
 // us to approximate `'x` one way or the other.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
@@ -29,7 +29,7 @@ fn case1() {
     let a = 0;
     let cell = Cell::new(&a);
     foo(cell, |cell_a, cell_x| {
-        //~^ WARNING not reporting region error due to -Znll
+        //~^ WARNING not reporting region error due to nll
         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
         //~^ ERROR does not outlive free region
     })
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index d39cdc34471..6480cbe4431 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:31:5
    |
 LL |     foo(cell, |cell_a, cell_x| {
@@ -15,7 +15,7 @@ note: No external requirements
    |
 LL |       foo(cell, |cell_a, cell_x| {
    |  _______________^
-LL | |         //~^ WARNING not reporting region error due to -Znll
+LL | |         //~^ WARNING not reporting region error due to nll
 LL | |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
 LL | |         //~^ ERROR does not outlive free region
 LL | |     })
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs
index c66472d5ce9..df715c52921 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs
@@ -16,7 +16,7 @@
 // FIXME(#45827) Because of shortcomings in the MIR type checker,
 // these errors are not (yet) reported.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
@@ -46,7 +46,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
         //~^ ERROR does not outlive free region
 
         // Only works if 'x: 'y:
-        demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll
+        demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
     });
 }
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index 3131142ec73..6dcc8421177 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -1,7 +1,7 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:49:9
    |
-LL |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll
+LL |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 note: External requirements
@@ -12,7 +12,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
 LL | |         //~^ ERROR does not outlive free region
 LL | |
 LL | |         // Only works if 'x: 'y:
-LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll
+LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
 LL | |     });
    | |_____^
    |
@@ -31,7 +31,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
 LL | |         //~^ ERROR does not outlive free region
 LL | |
 LL | |         // Only works if 'x: 'y:
-LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to -Znll
+LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
 LL | |     });
    | |_____^
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs
index f4011a0e533..fdbb312572f 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs
@@ -17,7 +17,7 @@
 // FIXME(#45827) Because of shortcomings in the MIR type checker,
 // these errors are not (yet) reported.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
@@ -49,7 +49,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
         //~^ ERROR does not outlive free region
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
-        //~^ WARNING not reporting region error due to -Znll
+        //~^ WARNING not reporting region error due to nll
     });
 }
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index 5b038653b60..1291f2e9901 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:51:9
    |
 LL |         demand_y(x, y, x.get())
@@ -12,7 +12,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x,
 LL | |         //~^ ERROR does not outlive free region
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
-LL | |         //~^ WARNING not reporting region error due to -Znll
+LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     });
    | |_____^
    |
@@ -31,7 +31,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x,
 LL | |         //~^ ERROR does not outlive free region
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
-LL | |         //~^ WARNING not reporting region error due to -Znll
+LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     });
    | |_____^
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs
index d163f304ae5..0449dc1d1a7 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.rs
@@ -15,7 +15,7 @@
 // relationships. In the 'main' variant, there are a number of
 // anonymous regions as well.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
@@ -47,7 +47,7 @@ fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
         //~^ ERROR lifetime mismatch
 
         // Only works if 'x: 'y:
-        demand_y(outlives1, outlives2, x.get()) //~ WARNING not reporting region error due to -Znll
+        demand_y(outlives1, outlives2, x.get()) //~ WARNING not reporting region error due to nll
     });
 }
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
index 475fdd94781..d1824a94151 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -1,7 +1,7 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-approximated-val.rs:50:9
    |
-LL |         demand_y(outlives1, outlives2, x.get()) //~ WARNING not reporting region error due to -Znll
+LL |         demand_y(outlives1, outlives2, x.get()) //~ WARNING not reporting region error due to nll
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 note: External requirements
@@ -12,7 +12,7 @@ LL |       establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y|
 LL | |         //~^ ERROR lifetime mismatch
 LL | |
 LL | |         // Only works if 'x: 'y:
-LL | |         demand_y(outlives1, outlives2, x.get()) //~ WARNING not reporting region error due to -Znll
+LL | |         demand_y(outlives1, outlives2, x.get()) //~ WARNING not reporting region error due to nll
 LL | |     });
    | |_____^
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs
index 1ccfa61f4ce..c21c824b22c 100644
--- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.rs
@@ -13,7 +13,7 @@
 // need to propagate; but in fact we do because identity of free
 // regions is erased.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 // compile-pass
 
 #![feature(rustc_attrs)]
diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
index ab4faaca756..d6eeda881da 100644
--- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-despite-same-free-region.rs:54:21
    |
 LL |             let p = x.get();
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs
index eb512a3b9b1..7699d101734 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs
@@ -17,7 +17,7 @@
 // as it knows of no relationships between `'x` and any
 // non-higher-ranked regions.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
@@ -45,7 +45,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
-        //~^ WARN not reporting region error due to -Znll
+        //~^ WARN not reporting region error due to nll
         //~| ERROR does not outlive free region
     });
 }
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index ce808f56b42..ffae47bd081 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
    |
 LL |         demand_y(x, y, x.get())
@@ -17,7 +17,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
    |  _______________________________________________^
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
-LL | |         //~^ WARN not reporting region error due to -Znll
+LL | |         //~^ WARN not reporting region error due to nll
 LL | |         //~| ERROR does not outlive free region
 LL | |     });
    | |_____^
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs
index 93074246429..afb61b221be 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs
@@ -17,7 +17,7 @@
 // as it only knows of regions that `'x` is outlived by, and none that
 // `'x` outlives.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
@@ -49,7 +49,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
-        //~^ WARN not reporting region error due to -Znll
+        //~^ WARN not reporting region error due to nll
         //~| ERROR does not outlive free region
     });
 }
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 547ff75bac6..01af756b833 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
    |
 LL |         demand_y(x, y, x.get())
@@ -17,7 +17,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x,
    |  _______________________________________________^
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
-LL | |         //~^ WARN not reporting region error due to -Znll
+LL | |         //~^ WARN not reporting region error due to nll
 LL | |         //~| ERROR does not outlive free region
 LL | |     });
    | |_____^
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
index 91796355752..7baf24f88f8 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.rs
@@ -14,7 +14,7 @@
 // the same `'a` for which it implements `Trait`, which can only be the `'a`
 // from the function definition.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
@@ -53,7 +53,7 @@ where
         // The latter does not hold.
 
         require(value);
-        //~^ WARNING not reporting region error due to -Znll
+        //~^ WARNING not reporting region error due to nll
     });
 }
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
index 5bdfc7e935f..a8b4ed52801 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/propagate-from-trait-match.rs:55:9
    |
 LL |         require(value);
@@ -13,7 +13,7 @@ LL | |         //~^ ERROR the parameter type `T` may not live long enough
 LL | |
 LL | |         // This function call requires that
 ...  |
-LL | |         //~^ WARNING not reporting region error due to -Znll
+LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     });
    | |_____^
    |
@@ -35,7 +35,7 @@ LL | |         //~^ ERROR the parameter type `T` may not live long enough
 LL | |
 LL | |         // This function call requires that
 ...  |
-LL | |         //~^ WARNING not reporting region error due to -Znll
+LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     });
    | |_____^
    |
diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs
index ac21fe25bd1..a6b2e531ac2 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs
+++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs
@@ -13,11 +13,11 @@
 // a variety of errors from the older, AST-based machinery (notably
 // borrowck), and then we get the NLL error at the end.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 fn foo(x: &u32) -> &'static u32 {
     &*x
-        //~^ WARN not reporting region error due to -Znll
+        //~^ WARN not reporting region error due to nll
         //~| ERROR explicit lifetime required in the type of `x`
 }
 
diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr
index 1e93ae1ee07..a823e62d3b8 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr
+++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/region-lbr-anon-does-not-outlive-static.rs:19:5
    |
 LL |     &*x
diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs
index a1be8e85185..dedbd8df41b 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs
+++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs
@@ -13,11 +13,11 @@
 // a variety of errors from the older, AST-based machinery (notably
 // borrowck), and then we get the NLL error at the end.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 fn foo<'a>(x: &'a u32) -> &'static u32 {
     &*x
-        //~^ WARN not reporting region error due to -Znll
+        //~^ WARN not reporting region error due to nll
         //~| ERROR does not outlive free region
 }
 
diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
index ac3bf4b459f..9520b446303 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
+++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5
    |
 LL |     &*x
diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs
index 00b09e2ab21..8598668bef5 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs
+++ b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs
@@ -13,11 +13,11 @@
 // a variety of errors from the older, AST-based machinery (notably
 // borrowck), and then we get the NLL error at the end.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 {
     &*x
-        //~^ WARN not reporting region error due to -Znll
+        //~^ WARN not reporting region error due to nll
         //~| ERROR lifetime mismatch
 }
 
diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr
index 3af6d7d21f7..415aefdeee9 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr
+++ b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/region-lbr1-does-not-outlive-ebr2.rs:19:5
    |
 LL |     &*x
diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs b/src/test/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs
index 7454a8e71f2..6d2bb309802 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs
+++ b/src/test/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs
@@ -11,7 +11,7 @@
 // Basic test for free regions in the NLL code. This test does not
 // report an error because of the (implied) bound that `'b: 'a`.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 // compile-pass
 
 #![allow(warnings)]
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs
index 754df4f2c5d..60f82ca0eef 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs
@@ -12,14 +12,14 @@
 // the first, but actually returns the second. This should fail within
 // the closure.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![feature(rustc_attrs)]
 
 #[rustc_regions]
 fn test() {
     expect_sig(|a, b| b); // ought to return `a`
-    //~^ WARN not reporting region error due to -Znll
+    //~^ WARN not reporting region error due to nll
     //~| ERROR does not outlive free region
 }
 
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index b34f4c470df..4d021fb5454 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/return-wrong-bound-region.rs:21:23
    |
 LL |     expect_sig(|a, b| b); // ought to return `a`
@@ -26,7 +26,7 @@ note: No external requirements
    |
 LL | / fn test() {
 LL | |     expect_sig(|a, b| b); // ought to return `a`
-LL | |     //~^ WARN not reporting region error due to -Znll
+LL | |     //~^ WARN not reporting region error due to nll
 LL | |     //~| ERROR does not outlive free region
 LL | | }
    | |_^
diff --git a/src/test/ui/nll/constant.rs b/src/test/ui/nll/constant.rs
index 589d8ffd28f..10ce0652d43 100644
--- a/src/test/ui/nll/constant.rs
+++ b/src/test/ui/nll/constant.rs
@@ -11,7 +11,7 @@
 // Test that MIR borrowck and NLL analysis can handle constants of
 // arbitrary types without ICEs.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 // compile-pass
 
 const HI: &str = "hi";
diff --git a/src/test/ui/nll/drop-may-dangle.rs b/src/test/ui/nll/drop-may-dangle.rs
index 6dcbe0a528d..b357b3facf9 100644
--- a/src/test/ui/nll/drop-may-dangle.rs
+++ b/src/test/ui/nll/drop-may-dangle.rs
@@ -12,7 +12,7 @@
 // in the type of `p` includes the points after `&v[0]` up to (but not
 // including) the call to `use_x`. The `else` branch is not included.
 
-// compile-flags:-Znll -Zborrowck=mir
+// compile-flags:-Zborrowck=mir
 // compile-pass
 
 #![allow(warnings)]
diff --git a/src/test/ui/nll/drop-no-may-dangle.rs b/src/test/ui/nll/drop-no-may-dangle.rs
index e5478e39fec..51360931631 100644
--- a/src/test/ui/nll/drop-no-may-dangle.rs
+++ b/src/test/ui/nll/drop-no-may-dangle.rs
@@ -13,7 +13,7 @@
 // because of destructor. (Note that the stderr also identifies this
 // destructor in the error message.)
 
-// compile-flags:-Znll -Zborrowck=mir
+// compile-flags:-Zborrowck=mir
 
 #![allow(warnings)]
 #![feature(dropck_eyepatch)]
diff --git a/src/test/ui/nll/get_default.rs b/src/test/ui/nll/get_default.rs
index e5944e75e42..728c84695ea 100644
--- a/src/test/ui/nll/get_default.rs
+++ b/src/test/ui/nll/get_default.rs
@@ -13,7 +13,7 @@
 // a variety of errors from the older, AST-based machinery (notably
 // borrowck), and then we get the NLL error at the end.
 
-// compile-flags:-Znll -Zborrowck=compare
+// compile-flags:-Zborrowck=compare
 
 struct Map {
 }
diff --git a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs
index d4df2a01c81..5538eca3629 100644
--- a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs
+++ b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll
+//compile-flags: -Z emit-end-regions -Zborrowck=mir
 
 
 #![allow(warnings)]
diff --git a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs b/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs
index 7e8a4e0ec95..ae815a5efe9 100644
--- a/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs
+++ b/src/test/ui/nll/maybe-initialized-drop-uninitialized.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//compile-flags: -Z emit-end-regions -Zborrowck=mir -Z nll
+// compile-flags: -Z emit-end-regions -Zborrowck=mir
 // compile-pass
 
 #![allow(warnings)]
diff --git a/src/test/ui/nll/maybe-initialized-drop-with-fragment.rs b/src/test/ui/nll/maybe-initialized-drop-with-fragment.rs
index 2eb90dca702..00d146e0f02 100644
--- a/src/test/ui/nll/maybe-initialized-drop-with-fragment.rs
+++ b/src/test/ui/nll/maybe-initialized-drop-with-fragment.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll
+//compile-flags: -Z emit-end-regions -Zborrowck=mir
 
 #![allow(warnings)]
 
diff --git a/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs b/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs
index f639d8f243f..cd46014a7f5 100644
--- a/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs
+++ b/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll
+//compile-flags: -Z emit-end-regions -Zborrowck=mir
 
 #![allow(warnings)]
 
diff --git a/src/test/ui/nll/maybe-initialized-drop.rs b/src/test/ui/nll/maybe-initialized-drop.rs
index c2cc479d28e..9a3aca34620 100644
--- a/src/test/ui/nll/maybe-initialized-drop.rs
+++ b/src/test/ui/nll/maybe-initialized-drop.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//compile-flags: -Z emit-end-regions -Zborrowck=mir -Znll
+//compile-flags: -Z emit-end-regions -Zborrowck=mir
 
 #![allow(warnings)]
 
diff --git a/src/test/ui/nll/projection-return.rs b/src/test/ui/nll/projection-return.rs
index 1515911fe87..c1abcb434e6 100644
--- a/src/test/ui/nll/projection-return.rs
+++ b/src/test/ui/nll/projection-return.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir
+// compile-flags:-Zborrowck=mir
 // compile-pass
 
 #![feature(rustc_attrs)]
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs
index 571bd9fd76e..f21127064d4 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs
+++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
 
@@ -19,7 +19,7 @@ impl<'a, T> Foo<'a> for T { }
 
 fn foo<'a, T>(x: &T) -> impl Foo<'a> {
     x
-        //~^ WARNING not reporting region error due to -Znll
+        //~^ WARNING not reporting region error due to nll
         //~| ERROR explicit lifetime required in the type of `x` [E0621]
 }
 
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
index 92e4f72da3a..f836960a28c 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
+++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/impl-trait-captures.rs:21:5
    |
 LL |     x
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs b/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs
index 2e0671f1a51..182e11da082 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs
+++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
 
 use std::fmt::Debug;
 
 fn no_region<'a, T>(x: Box<T>) -> impl Debug + 'a
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
 where
     T: Debug,
 {
@@ -31,7 +31,7 @@ where
 }
 
 fn wrong_region<'a, 'b, T>(x: Box<T>) -> impl Debug + 'a
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
 where
     T: 'b + Debug,
 {
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
index 2b90d53774e..50b80282e62 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
+++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr
@@ -1,10 +1,10 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/impl-trait-outlives.rs:17:35
    |
 LL | fn no_region<'a, T>(x: Box<T>) -> impl Debug + 'a
    |                                   ^^^^^^^^^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/impl-trait-outlives.rs:33:42
    |
 LL | fn wrong_region<'a, 'b, T>(x: Box<T>) -> impl Debug + 'a
diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs b/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs
index 0ec6d7b74ad..d8f077467d9 100644
--- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs
+++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 // Test that we can deduce when projections like `T::Item` outlive the
 // function body. Test that this does not imply that `T: 'a` holds.
@@ -43,7 +43,7 @@ where
 #[rustc_errors]
 fn generic2<T: Iterator>(value: T) {
     twice(value, |value_ref, item| invoke2(value_ref, item));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
 }
 
diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
index fa53967ed3a..0a2bd324765 100644
--- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-implied-bounds.rs:45:36
    |
 LL |     twice(value, |value_ref, item| invoke2(value_ref, item));
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs
index 0493bd1ea0d..7b3ed6a94fc 100644
--- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 // Tests closures that propagate an outlives relationship to their
 // creator where the subject is a projection with no regions (`<T as
@@ -34,7 +34,7 @@ where
     T: Iterator,
 {
     with_signature(x, |mut y| Box::new(y.next()))
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR the associated type `<T as std::iter::Iterator>::Item` may not live long enough
 }
 
@@ -52,7 +52,7 @@ where
     T: 'b + Iterator,
 {
     with_signature(x, |mut y| Box::new(y.next()))
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR the associated type `<T as std::iter::Iterator>::Item` may not live long enough
 }
 
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
index bcdf984f65a..0efbbdff12a 100644
--- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
@@ -1,10 +1,10 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-no-regions-closure.rs:36:31
    |
 LL |     with_signature(x, |mut y| Box::new(y.next()))
    |                               ^^^^^^^^^^^^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-no-regions-closure.rs:54:31
    |
 LL |     with_signature(x, |mut y| Box::new(y.next()))
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs
index 5f2e84e247a..32b73a51e11 100644
--- a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
 #![feature(dyn_trait)]
@@ -22,7 +22,7 @@ where
     T: Iterator,
 {
     Box::new(x.next())
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| the associated type `<T as std::iter::Iterator>::Item` may not live long enough
 }
 
@@ -38,7 +38,7 @@ where
     T: 'b + Iterator,
 {
     Box::new(x.next())
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| the associated type `<T as std::iter::Iterator>::Item` may not live long enough
 }
 
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr
index 95851e7edc7..b2c5f28268d 100644
--- a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr
@@ -1,10 +1,10 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-no-regions-fn.rs:24:5
    |
 LL |     Box::new(x.next())
    |     ^^^^^^^^^^^^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-no-regions-fn.rs:40:5
    |
 LL |     Box::new(x.next())
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs
index 9a5e04deddf..cfe2880bfed 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs
@@ -22,7 +22,7 @@
 //
 // Ensuring that both `T: 'a` and `'b: 'a` holds does work (`elements_outlive`).
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
 #![feature(dyn_trait)]
@@ -54,7 +54,7 @@ where
     T: Anything<'b>,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
     //~| ERROR does not outlive free region
 }
@@ -66,7 +66,7 @@ where
     'a: 'a,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
     //~| ERROR does not outlive free region
 }
@@ -88,7 +88,7 @@ where
     // can do better here with a more involved verification step.
 
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
     //~| ERROR free region `ReEarlyBound(1, 'b)` does not outlive free region `ReEarlyBound(0, 'a)`
 }
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
index aa45cf18701..0d5a2dc7c55 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
@@ -1,16 +1,16 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-one-region-closure.rs:56:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                                       ^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-one-region-closure.rs:68:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                                       ^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-one-region-closure.rs:90:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs
index 232025b5735..16e91f2708f 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs
@@ -14,7 +14,7 @@
 // case, the best way to satisfy the trait bound is to show that `'b:
 // 'a`, which can be done in various ways.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
 #![feature(dyn_trait)]
@@ -46,7 +46,7 @@ where
     T: Anything<'b>,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR does not outlive free region
 }
 
@@ -57,7 +57,7 @@ where
     'a: 'a,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR does not outlive free region
 }
 
@@ -78,7 +78,7 @@ where
     // can do better here with a more involved verification step.
 
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR does not outlive free region
 }
 
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
index 7a8010ad8e0..d4aca8380b4 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
@@ -1,16 +1,16 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-one-region-trait-bound-closure.rs:48:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                                       ^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-one-region-trait-bound-closure.rs:59:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                                       ^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-one-region-trait-bound-closure.rs:80:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs
index a1bdd1b89f9..0d42636c844 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs
@@ -12,7 +12,7 @@
 // outlive `'static`. In this case, we don't get any errors, and in fact
 // we don't even propagate constraints from the closures to the callers.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 // compile-pass
 
 #![allow(warnings)]
diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs
index e3cee00ed4e..7c8ef140a29 100644
--- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs
+++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs
@@ -15,7 +15,7 @@
 // the trait bound, and hence we propagate it to the caller as a type
 // test.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
 #![feature(dyn_trait)]
@@ -47,7 +47,7 @@ where
     T: Anything<'b, 'c>,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may not live long enough
 }
 
@@ -58,7 +58,7 @@ where
     'a: 'a,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
 }
 
@@ -79,7 +79,7 @@ where
     // can do better here with a more involved verification step.
 
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
 }
 
@@ -107,7 +107,7 @@ where
     T: Anything<'b, 'b>,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR does not outlive free region
 }
 
diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
index c7cbdaec339..7e36e467e4e 100644
--- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
@@ -1,22 +1,22 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-two-region-trait-bound-closure.rs:49:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                                       ^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-two-region-trait-bound-closure.rs:60:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                                       ^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-two-region-trait-bound-closure.rs:81:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                                       ^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/projection-two-region-trait-bound-closure.rs:109:39
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs
index 423747a6bd6..80b42c29563 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
 #![feature(dyn_trait)]
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 997cc57cfa2..c8feaddff93 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -1,16 +1,16 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-closure-approximate-lower-bound.rs:35:31
    |
 LL |     twice(cell, value, |a, b| invoke(a, b));
    |                               ^^^^^^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-closure-approximate-lower-bound.rs:43:31
    |
 LL |     twice(cell, value, |a, b| invoke(a, b));
    |                               ^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-closure-approximate-lower-bound.rs:43:31
    |
 LL |     twice(cell, value, |a, b| invoke(a, b));
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs
index 95a483b3c35..50763a1d508 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
 #![feature(dyn_trait)]
@@ -35,7 +35,7 @@ where
     // `'a` (and subsequently reports an error).
 
     with_signature(x, |y| y)
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
 }
 
@@ -51,7 +51,7 @@ where
     T: 'b + Debug,
 {
     x
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
 }
 
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
index ba08bc1ff7b..500595e0c5d 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
@@ -1,10 +1,10 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-closure-outlives-from-return-type.rs:37:27
    |
 LL |     with_signature(x, |y| y)
    |                           ^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-closure-outlives-from-return-type.rs:53:5
    |
 LL |     x
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs
index 1149f250a46..b70fc2b2ec4 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs
@@ -12,7 +12,7 @@
 // `correct_region` for an explanation of how this test is setup; it's
 // somewhat intricate.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 
 #![allow(warnings)]
 #![feature(dyn_trait)]
@@ -43,7 +43,7 @@ fn no_region<'a, T>(a: Cell<&'a ()>, b: T) {
         // function, there is no where clause *anywhere*, and hence we
         // get an error (but reported by the closure creator).
         require(&x, &y)
-        //~^ WARNING not reporting region error due to -Znll
+        //~^ WARNING not reporting region error due to nll
     })
 }
 
@@ -77,7 +77,7 @@ where
         //~^ ERROR the parameter type `T` may not live long enough
         // See `correct_region`
         require(&x, &y)
-        //~^ WARNING not reporting region error due to -Znll
+        //~^ WARNING not reporting region error due to nll
     })
 }
 
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
index fcdb0b0a4a9..4d8a66ba8e1 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
@@ -1,10 +1,10 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:45:9
    |
 LL |         require(&x, &y)
    |         ^^^^^^^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:79:9
    |
 LL |         require(&x, &y)
@@ -19,7 +19,7 @@ LL | |         //~^ ERROR the parameter type `T` may not live long enough
 LL | |         //
 LL | |         // See `correct_region`, which explains the point of this
 ...  |
-LL | |         //~^ WARNING not reporting region error due to -Znll
+LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     })
    | |_____^
    |
@@ -40,7 +40,7 @@ LL | |         //~^ ERROR the parameter type `T` may not live long enough
 LL | |         //
 LL | |         // See `correct_region`, which explains the point of this
 ...  |
-LL | |         //~^ WARNING not reporting region error due to -Znll
+LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     })
    | |_____^
    |
@@ -109,7 +109,7 @@ LL |       with_signature(a, b, |x, y| {
 LL | |         //~^ ERROR the parameter type `T` may not live long enough
 LL | |         // See `correct_region`
 LL | |         require(&x, &y)
-LL | |         //~^ WARNING not reporting region error due to -Znll
+LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     })
    | |_____^
    |
@@ -130,7 +130,7 @@ LL |       with_signature(a, b, |x, y| {
 LL | |         //~^ ERROR the parameter type `T` may not live long enough
 LL | |         // See `correct_region`
 LL | |         require(&x, &y)
-LL | |         //~^ WARNING not reporting region error due to -Znll
+LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     })
    | |_____^
    |
diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs b/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs
index e66c1853b64..fb4ea63f853 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn-body.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir
+// compile-flags:-Zborrowck=mir
 
 // Test that we assume that universal types like `T` outlive the
 // function body.
@@ -28,7 +28,7 @@ fn region_within_body<T>(t: T) {
 // Error here, because T: 'a is not satisfied.
 fn region_static<'a, T>(cell: Cell<&'a usize>, t: T) {
     outlives(cell, t)
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
 }
 
diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr
index 34ed709a273..0596861e67b 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr
@@ -1,4 +1,4 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-fn-body.rs:30:5
    |
 LL |     outlives(cell, t)
diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn.rs b/src/test/ui/nll/ty-outlives/ty-param-fn.rs
index aa3a03afa35..42d662e1419 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-fn.rs
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir
+// compile-flags:-Zborrowck=mir
 
 #![allow(warnings)]
 #![feature(dyn_trait)]
@@ -20,7 +20,7 @@ where
     T: Debug,
 {
     x
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| the parameter type `T` may not live long enough
 }
 
@@ -36,7 +36,7 @@ where
     T: 'b + Debug,
 {
     x
-    //~^ WARNING not reporting region error due to -Znll
+    //~^ WARNING not reporting region error due to nll
     //~| the parameter type `T` may not live long enough
 }
 
diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr
index 98ccfc52029..0d09cac8c38 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-fn.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr
@@ -1,10 +1,10 @@
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-fn.rs:22:5
    |
 LL |     x
    |     ^
 
-warning: not reporting region error due to -Znll
+warning: not reporting region error due to nll
   --> $DIR/ty-param-fn.rs:38:5
    |
 LL |     x
diff --git a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs
index d4ae9b20e56..51927d353ec 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs
+++ b/src/test/ui/nll/ty-outlives/ty-param-implied-bounds.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:-Znll -Zborrowck=mir -Zverbose
+// compile-flags:-Zborrowck=mir -Zverbose
 // compile-pass
 
 // Test that we assume that universal types like `T` outlive the
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 9fa176aa68c..e79aefb7236 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1696,7 +1696,7 @@ impl<'test> TestCx<'test> {
 
         match self.config.compare_mode {
             Some(CompareMode::Nll) => {
-                rustc.args(&["-Znll", "-Zborrowck=mir", "-Ztwo-phase-borrows"]);
+                rustc.args(&["-Zborrowck=mir", "-Ztwo-phase-borrows"]);
             },
             None => {},
         }