From 8eb789f4c763a43d4f2098243fb94d9551feb151 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Mon, 27 Aug 2018 14:14:26 -0400
Subject: [PATCH 1/5] region_infer.rs: add some debug!

---
 src/librustc_mir/borrow_check/nll/region_infer/mod.rs | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index bbdf2a9292210..268a42471ab93 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -698,7 +698,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // `ClosureOutlivesRequirement`.
         let r_scc = self.constraint_sccs.scc(*lower_bound);
         for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
+            debug!("try_promote_type_test: ur={:?}", ur);
+
             let non_local_ub = self.universal_region_relations.non_local_upper_bound(ur);
+            debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub);
 
             assert!(self.universal_regions.is_universal_region(non_local_ub));
             assert!(
@@ -707,11 +710,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 .is_local_free_region(non_local_ub)
             );
 
-            propagated_outlives_requirements.push(ClosureOutlivesRequirement {
+            let requirement = ClosureOutlivesRequirement {
                 subject,
                 outlived_free_region: non_local_ub,
                 blame_span: locations.span(mir),
-            });
+            };
+            debug!("try_promote_type_test: pushing {:#?}", requirement);
+            propagated_outlives_requirements.push(requirement);
         }
         true
     }

From b7f871363be760f72f5e52152071b8f6124feac8 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Mon, 27 Aug 2018 14:14:40 -0400
Subject: [PATCH 2/5] region_infer: rustfmt

---
 .../borrow_check/nll/region_infer/mod.rs      | 28 ++++++++-----------
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 268a42471ab93..bc26cb7a97a10 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -686,7 +686,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             test: _,
         } = type_test;
 
-
         let generic_ty = generic_kind.to_ty(tcx);
         let subject = match self.try_promote_type_test_subject(infcx, generic_ty) {
             Some(s) => s,
@@ -704,11 +703,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub);
 
             assert!(self.universal_regions.is_universal_region(non_local_ub));
-            assert!(
-                !self
-                .universal_regions
-                .is_local_free_region(non_local_ub)
-            );
+            assert!(!self.universal_regions.is_local_free_region(non_local_ub));
 
             let requirement = ClosureOutlivesRequirement {
                 subject,
@@ -922,8 +917,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // now). Therefore, the sup-region outlives the sub-region if,
         // for each universal region R1 in the sub-region, there
         // exists some region R2 in the sup-region that outlives R1.
-        let universal_outlives = self
-            .scc_values
+        let universal_outlives = self.scc_values
             .universal_regions_outlived_by(sub_region_scc)
             .all(|r1| {
                 self.scc_values
@@ -1034,8 +1028,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // (because `fr` includes `end(o)`).
         for shorter_fr in self.scc_values.universal_regions_outlived_by(longer_fr_scc) {
             // If it is known that `fr: o`, carry on.
-            if self
-                .universal_region_relations
+            if self.universal_region_relations
                 .outlives(longer_fr, shorter_fr)
             {
                 continue;
@@ -1051,8 +1044,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             if let Some(propagated_outlives_requirements) = propagated_outlives_requirements {
                 // Shrink `fr` until we find a non-local region (if we do).
                 // We'll call that `fr-` -- it's ever so slightly smaller than `fr`.
-                if let Some(fr_minus) = self
-                    .universal_region_relations
+                if let Some(fr_minus) = self.universal_region_relations
                     .non_local_lower_bound(longer_fr)
                 {
                     debug!("check_universal_region: fr_minus={:?}", fr_minus);
@@ -1061,8 +1053,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     // region. (We always will.)  We'll call that
                     // `shorter_fr+` -- it's ever so slightly larger than
                     // `fr`.
-                    let shorter_fr_plus = self
-                        .universal_region_relations
+                    let shorter_fr_plus = self.universal_region_relations
                         .non_local_upper_bound(shorter_fr);
                     debug!(
                         "check_universal_region: shorter_fr_plus={:?}",
@@ -1122,8 +1113,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let error_region = match error_element {
             RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
             RegionElement::RootUniversalRegion(r) => r,
-            RegionElement::SubUniversalRegion(error_ui) => self
-                .definitions
+            RegionElement::SubUniversalRegion(error_ui) => self.definitions
                 .iter_enumerated()
                 .filter_map(|(r, definition)| match definition.origin {
                     NLLRegionVariableOrigin::BoundRegion(ui) if error_ui == ui => Some(r),
@@ -1220,7 +1210,11 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
         // into a vector.  These are the regions that we will be
         // relating to one another.
         let closure_mapping = &UniversalRegions::closure_mapping(
-            tcx, user_closure_ty, self.num_external_vids, tcx.closure_base_def_id(closure_def_id));
+            tcx,
+            user_closure_ty,
+            self.num_external_vids,
+            tcx.closure_base_def_id(closure_def_id),
+        );
         debug!("apply_requirements: closure_mapping={:?}", closure_mapping);
 
         // Create the predicates.

From db169e53e5c88484718c1be2be6dcb7dab4a278f Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Mon, 27 Aug 2018 15:10:05 -0400
Subject: [PATCH 3/5] move `annotate` onto a method of `UniversalRegions`

This allows it to print out the "late-bound regions" from the closure
context more easily. Besides, all the state that is being printed it
is private to the `UniversalRegions`.
---
 src/librustc_mir/borrow_check/nll/mod.rs      |  6 +-
 .../nll/region_infer/annotation.rs            | 56 ------------------
 .../borrow_check/nll/region_infer/mod.rs      |  8 ++-
 .../borrow_check/nll/universal_regions.rs     | 58 +++++++++++++++++++
 ...pagate-approximated-fail-no-postdom.stderr |  3 +
 .../propagate-approximated-ref.stderr         |  2 +
 ...oximated-shorter-to-static-no-bound.stderr |  2 +
 ...mated-shorter-to-static-wrong-bound.stderr |  2 +
 .../propagate-approximated-val.stderr         |  2 +
 .../propagate-despite-same-free-region.stderr |  1 +
 ...ail-to-approximate-longer-no-bounds.stderr |  2 +
 ...-to-approximate-longer-wrong-bounds.stderr |  2 +
 ...e-region-trait-bound-static-closure.stderr |  6 ++
 13 files changed, 89 insertions(+), 61 deletions(-)
 delete mode 100644 src/librustc_mir/borrow_check/nll/region_infer/annotation.rs

diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 693210da8d3a8..7cab0acb4326a 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -276,7 +276,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>(
     infcx: &InferCtxt<'a, 'gcx, 'tcx>,
     mir: &Mir<'tcx>,
     mir_def_id: DefId,
-    regioncx: &RegionInferenceContext,
+    regioncx: &RegionInferenceContext<'tcx>,
     closure_region_requirements: &Option<ClosureRegionRequirements>,
     errors_buffer: &mut Vec<Diagnostic>,
 ) {
@@ -299,7 +299,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>(
             .diagnostic()
             .span_note_diag(mir.span, "External requirements");
 
-        regioncx.annotate(&mut err);
+        regioncx.annotate(tcx, &mut err);
 
         err.note(&format!(
             "number of external vids: {}",
@@ -319,7 +319,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>(
             .sess
             .diagnostic()
             .span_note_diag(mir.span, "No external requirements");
-        regioncx.annotate(&mut err);
+        regioncx.annotate(tcx, &mut err);
 
         err.buffer(errors_buffer);
     }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/annotation.rs b/src/librustc_mir/borrow_check/nll/region_infer/annotation.rs
deleted file mode 100644
index 7cde06be0c23b..0000000000000
--- a/src/librustc_mir/borrow_check/nll/region_infer/annotation.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 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.
-
-//! As part of the NLL unit tests, you can annotate a function with
-//! `#[rustc_regions]`, and we will emit information about the region
-//! inference context and -- in particular -- the external constraints
-//! that this region imposes on others. The methods in this file
-//! handle the part about dumping the inference context internal
-//! state.
-
-use borrow_check::nll::region_infer::RegionInferenceContext;
-use borrow_check::nll::universal_regions::DefiningTy;
-use rustc_errors::DiagnosticBuilder;
-
-impl<'tcx> RegionInferenceContext<'tcx> {
-    /// Write out our state into the `.mir` files.
-    pub(crate) fn annotate(&self, err: &mut DiagnosticBuilder<'_>) {
-        match self.universal_regions.defining_ty {
-            DefiningTy::Closure(def_id, substs) => {
-                err.note(&format!(
-                    "defining type: {:?} with closure substs {:#?}",
-                    def_id,
-                    &substs.substs[..]
-                ));
-            }
-            DefiningTy::Generator(def_id, substs, _) => {
-                err.note(&format!(
-                    "defining type: {:?} with generator substs {:#?}",
-                    def_id,
-                    &substs.substs[..]
-                ));
-            }
-            DefiningTy::FnDef(def_id, substs) => {
-                err.note(&format!(
-                    "defining type: {:?} with substs {:#?}",
-                    def_id,
-                    &substs[..]
-                ));
-            }
-            DefiningTy::Const(def_id, substs) => {
-                err.note(&format!(
-                    "defining constant type: {:?} with substs {:#?}",
-                    def_id,
-                    &substs[..]
-                ));
-            }
-        }
-    }
-}
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index bc26cb7a97a10..46b3c70869528 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -29,11 +29,10 @@ use rustc::util::common;
 use rustc_data_structures::graph::scc::Sccs;
 use rustc_data_structures::indexed_set::IdxSet;
 use rustc_data_structures::indexed_vec::IndexVec;
-use rustc_errors::Diagnostic;
+use rustc_errors::{DiagnosticBuilder, Diagnostic};
 
 use std::rc::Rc;
 
-mod annotation;
 mod dump_mir;
 mod error_reporting;
 mod graphviz;
@@ -359,6 +358,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         self.universal_regions.to_region_vid(r)
     }
 
+    /// Add annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`.
+    crate fn annotate(&self, tcx: TyCtxt<'_, '_, 'tcx>, err: &mut DiagnosticBuilder<'_>) {
+        self.universal_regions.annotate(tcx, err)
+    }
+
     /// Returns true if the region `r` contains the point `p`.
     ///
     /// Panics if called before `solve()` executes,
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index 5115312825605..19ffd971fcbf9 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -31,6 +31,7 @@ use rustc::ty::subst::Substs;
 use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid, Ty, TyCtxt};
 use rustc::util::nodemap::FxHashMap;
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use rustc_errors::DiagnosticBuilder;
 use std::iter;
 use syntax::ast;
 
@@ -310,6 +311,63 @@ impl<'tcx> UniversalRegions<'tcx> {
     pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
         self.indices.to_region_vid(r)
     }
+
+    /// As part of the NLL unit tests, you can annotate a function with
+    /// `#[rustc_regions]`, and we will emit information about the region
+    /// inference context and -- in particular -- the external constraints
+    /// that this region imposes on others. The methods in this file
+    /// handle the part about dumping the inference context internal
+    /// state.
+    crate fn annotate(&self, tcx: TyCtxt<'_, '_, 'tcx>, err: &mut DiagnosticBuilder<'_>) {
+        match self.defining_ty {
+            DefiningTy::Closure(def_id, substs) => {
+                err.note(&format!(
+                    "defining type: {:?} with closure substs {:#?}",
+                    def_id,
+                    &substs.substs[..]
+                ));
+
+                let closure_base_def_id = tcx.closure_base_def_id(def_id);
+                for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| {
+                    err.note(&format!(
+                        "late-bound region {:?} is {:?}",
+                        r,
+                        self.to_region_vid(r),
+                    ));
+                });
+            }
+            DefiningTy::Generator(def_id, substs, _) => {
+                err.note(&format!(
+                    "defining type: {:?} with generator substs {:#?}",
+                    def_id,
+                    &substs.substs[..]
+                ));
+
+                let closure_base_def_id = tcx.closure_base_def_id(def_id);
+                for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| {
+                    err.note(&format!(
+                        "late-bound region {:?} is {:?}",
+                        r,
+                        self.to_region_vid(r),
+                    ));
+                });
+            }
+            DefiningTy::FnDef(def_id, substs) => {
+                err.note(&format!(
+                    "defining type: {:?} with substs {:#?}",
+                    def_id,
+                    &substs[..]
+                ));
+            }
+            DefiningTy::Const(def_id, substs) => {
+                err.note(&format!(
+                    "defining constant type: {:?} with substs {:#?}",
+                    def_id,
+                    &substs[..]
+                ));
+            }
+        }
+    }
 }
 
 struct UniversalRegionsBuilder<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
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 892910686433a..6f1712c03b612 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
@@ -12,6 +12,9 @@ LL | |         },
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'a)) is '_#4r
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]), BrNamed(crate0:DefIndex(1:19), 'c)) is '_#5r
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]), BrNamed(crate0:DefIndex(1:18), 'b)) is '_#6r
 
 error: unsatisfied lifetime constraints
   --> $DIR/propagate-approximated-fail-no-postdom.rs:56:13
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 1ff9374c21267..6bf6832229fec 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -14,6 +14,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_ref[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_ref[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#4r
    = note: number of external vids: 5
    = note: where '_#1r: '_#2r
 
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 f50864d946be9..c0555cf1b3f4e 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
@@ -15,6 +15,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) u32>))
            ]
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#2r
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
    = note: number of external vids: 4
    = note: where '_#1r: '_#0r
 
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 8a89320d10cad..49f3f2ba1cc05 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
@@ -14,6 +14,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#4r
    = note: number of external vids: 5
    = note: where '_#1r: '_#0r
 
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 71dbc412fef4c..95d196bdda6cc 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -14,6 +14,8 @@ LL | |     });
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_val[317d]::test[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_val[317d]::test[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#4r
    = note: number of external vids: 5
    = note: where '_#1r: '_#2r
 
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 d189385213fa1..25529634453da 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
@@ -12,6 +12,7 @@ LL | |         },
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_despite_same_free_region[317d]::supply[0]), BrNamed(crate0:DefIndex(1:15), 'a)) is '_#3r
    = note: number of external vids: 4
    = note: where '_#1r: '_#2r
 
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 a63c6b1670837..0154eefc134e5 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
@@ -13,6 +13,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#2r
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
 
 error: unsatisfied lifetime constraints
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
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 67510a5a81f11..269c826f57864 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
@@ -13,6 +13,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
+   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#4r
 
 error: unsatisfied lifetime constraints
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
index 136e143e80edf..9605677740f31 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
@@ -10,6 +10,8 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
+   = note: late-bound region ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#3r
+   = note: late-bound region ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:18), T)) is '_#4r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:42:1
@@ -40,6 +42,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
+   = note: late-bound region ReFree(DefId(0/0:9 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]), BrNamed(crate0:DefIndex(1:22), T)) is '_#4r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:50:1
@@ -72,6 +75,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
+   = note: late-bound region ReFree(DefId(0/0:10 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]), BrNamed(crate0:DefIndex(1:26), T)) is '_#4r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:59:1
@@ -104,6 +108,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
+   = note: late-bound region ReFree(DefId(0/0:11 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]), BrNamed(crate0:DefIndex(1:30), T)) is '_#4r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:78:1
@@ -135,6 +140,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
+   = note: late-bound region ReFree(DefId(0/0:12 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]), BrNamed(crate0:DefIndex(1:33), T)) is '_#3r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:87:1

From 43e758798c34581b313fae54d28e95fca628b167 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Mon, 27 Aug 2018 15:13:59 -0400
Subject: [PATCH 4/5] avoid propagating outlives obligations on locals if we
 can

---
 .../borrow_check/nll/region_infer/mod.rs      | 17 +++++++
 src/test/ui/nll/issue-53570.rs                | 46 +++++++++++++++++++
 2 files changed, 63 insertions(+)
 create mode 100644 src/test/ui/nll/issue-53570.rs

diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 46b3c70869528..cb15c88bb3e6f 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -701,6 +701,23 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // `ClosureOutlivesRequirement`.
         let r_scc = self.constraint_sccs.scc(*lower_bound);
         for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
+            // Check whether we can already prove that the "subject" outlives `ur`.
+            // If so, we don't have to propagate this requirement to our caller.
+            //
+            // To continue the example from the function, if we are trying to promote
+            // a requirement that `T: 'X`, and we know that `'X = '1 + '2` (i.e., the union
+            // `'1` and `'2`), then in this loop `ur` will be `'1` (and `'2`). So here
+            // we check whether `T: '1` is something we *can* prove. If so, no need
+            // to propagate that requirement.
+            //
+            // This is needed because -- particularly in the case
+            // where `ur` is a local bound -- we are sometimes in a
+            // position to prove things that our caller cannot.  See
+            // #53570 for an example.
+            if self.eval_region_test(mir, ur, &type_test.test) {
+                continue;
+            }
+
             debug!("try_promote_type_test: ur={:?}", ur);
 
             let non_local_ub = self.universal_region_relations.non_local_upper_bound(ur);
diff --git a/src/test/ui/nll/issue-53570.rs b/src/test/ui/nll/issue-53570.rs
new file mode 100644
index 0000000000000..9617e40ec39d9
--- /dev/null
+++ b/src/test/ui/nll/issue-53570.rs
@@ -0,0 +1,46 @@
+// Copyright 2018 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.
+
+// Regression test for #53570. Here, we need to propagate that `T: 'a`
+// but in some versions of NLL we were propagating a stronger
+// requirement that `T: 'static`. This arose because we actually had
+// to propagate both that `T: 'a` but also `T: 'b` where `'b` is the
+// higher-ranked lifetime that appears in the type of the closure
+// parameter `x` -- since `'b` cannot be expressed in the caller's
+// space, that got promoted th `'static`.
+//
+// compile-pass
+
+#![feature(nll)]
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+use std::cell::{RefCell, Ref};
+
+trait AnyVec<'a> {
+}
+
+trait GenericVec<T> {
+    fn unwrap<'a, 'b>(vec: &'b AnyVec<'a>) -> &'b [T] where T: 'a;
+}
+
+struct Scratchpad<'a> {
+    buffers: RefCell<Box<AnyVec<'a>>>,
+}
+
+impl<'a> Scratchpad<'a> {
+    fn get<T: GenericVec<T>>(&self) -> Ref<[T]>
+    where T: 'a
+    {
+        Ref::map(self.buffers.borrow(), |x| T::unwrap(x.as_ref()))
+    }
+}
+
+fn main() { }

From bb8c4c0db9257d1deccd4b31470724ac23e765e7 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Fri, 7 Sep 2018 13:35:16 -0400
Subject: [PATCH 5/5] print less info to stabilize tests

---
 .../borrow_check/nll/universal_regions.rs          | 14 ++++++++++----
 .../propagate-approximated-fail-no-postdom.stderr  |  6 +++---
 .../propagate-approximated-ref.stderr              |  4 ++--
 ...-approximated-shorter-to-static-no-bound.stderr |  4 ++--
 ...proximated-shorter-to-static-wrong-bound.stderr |  4 ++--
 .../propagate-approximated-val.stderr              |  4 ++--
 .../propagate-despite-same-free-region.stderr      |  2 +-
 ...ate-fail-to-approximate-longer-no-bounds.stderr |  4 ++--
 ...-fail-to-approximate-longer-wrong-bounds.stderr |  4 ++--
 .../projection-one-region-closure.stderr           |  1 +
 ...rojection-one-region-trait-bound-closure.stderr |  1 +
 ...on-one-region-trait-bound-static-closure.stderr |  7 +------
 ...rojection-two-region-trait-bound-closure.stderr |  2 ++
 ...ty-param-closure-approximate-lower-bound.stderr |  1 +
 ...param-closure-outlives-from-where-clause.stderr |  2 ++
 15 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index 19ffd971fcbf9..eb6f1a0677b2c 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -327,11 +327,15 @@ impl<'tcx> UniversalRegions<'tcx> {
                     &substs.substs[..]
                 ));
 
+                // FIXME: It'd be nice to print the late-bound regions
+                // here, but unfortunately these wind up stored into
+                // tests, and the resulting print-outs include def-ids
+                // and other things that are not stable across tests!
+                // So we just include the region-vid. Annoying.
                 let closure_base_def_id = tcx.closure_base_def_id(def_id);
                 for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| {
                     err.note(&format!(
-                        "late-bound region {:?} is {:?}",
-                        r,
+                        "late-bound region is {:?}",
                         self.to_region_vid(r),
                     ));
                 });
@@ -343,11 +347,13 @@ impl<'tcx> UniversalRegions<'tcx> {
                     &substs.substs[..]
                 ));
 
+                // FIXME: As above, we'd like to print out the region
+                // `r` but doing so is not stable across architectures
+                // and so forth.
                 let closure_base_def_id = tcx.closure_base_def_id(def_id);
                 for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| {
                     err.note(&format!(
-                        "late-bound region {:?} is {:?}",
-                        r,
+                        "late-bound region is {:?}",
                         self.to_region_vid(r),
                     ));
                 });
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 6f1712c03b612..fa14d496a1441 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
@@ -12,9 +12,9 @@ LL | |         },
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'a)) is '_#4r
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]), BrNamed(crate0:DefIndex(1:19), 'c)) is '_#5r
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]), BrNamed(crate0:DefIndex(1:18), 'b)) is '_#6r
+   = note: late-bound region is '_#4r
+   = note: late-bound region is '_#5r
+   = note: late-bound region is '_#6r
 
 error: unsatisfied lifetime constraints
   --> $DIR/propagate-approximated-fail-no-postdom.rs:56:13
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 6bf6832229fec..1af96b97e73bd 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -14,8 +14,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_ref[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_ref[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#4r
+   = note: late-bound region is '_#3r
+   = note: late-bound region is '_#4r
    = note: number of external vids: 5
    = note: where '_#1r: '_#2r
 
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 c0555cf1b3f4e..9de9e21ba43d2 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
@@ -15,8 +15,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) u32>))
            ]
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#2r
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
+   = note: late-bound region is '_#2r
+   = note: late-bound region is '_#3r
    = note: number of external vids: 4
    = note: where '_#1r: '_#0r
 
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 49f3f2ba1cc05..6acb675005540 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
@@ -14,8 +14,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#4r
+   = note: late-bound region is '_#3r
+   = note: late-bound region is '_#4r
    = note: number of external vids: 5
    = note: where '_#1r: '_#0r
 
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 95d196bdda6cc..e0902ca1ddbe8 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -14,8 +14,8 @@ LL | |     });
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_val[317d]::test[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_approximated_val[317d]::test[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#4r
+   = note: late-bound region is '_#3r
+   = note: late-bound region is '_#4r
    = note: number of external vids: 5
    = note: where '_#1r: '_#2r
 
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 25529634453da..a3f78507d8d0c 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
@@ -12,7 +12,7 @@ LL | |         },
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_despite_same_free_region[317d]::supply[0]), BrNamed(crate0:DefIndex(1:15), 'a)) is '_#3r
+   = note: late-bound region is '_#3r
    = note: number of external vids: 4
    = note: where '_#1r: '_#2r
 
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 0154eefc134e5..31cad6ba1b570 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
@@ -13,8 +13,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#2r
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
+   = note: late-bound region is '_#2r
+   = note: late-bound region is '_#3r
 
 error: unsatisfied lifetime constraints
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
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 269c826f57864..4e21816e8c0c4 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
@@ -13,8 +13,8 @@ LL | |     });
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]), BrNamed(crate0:DefIndex(1:17), 'b)) is '_#3r
-   = note: late-bound region ReFree(DefId(0/0:6 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#4r
+   = note: late-bound region is '_#3r
+   = note: late-bound region is '_#4r
 
 error: unsatisfied lifetime constraints
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
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 24f4bea1ba2f8..a91761f3ece2f 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
@@ -10,6 +10,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
+   = note: late-bound region is '_#3r
    = note: number of external vids: 4
    = note: where T: '_#2r
    = note: where '_#1r: '_#2r
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 df4f619b7763b..0064393f271ca 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
@@ -10,6 +10,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
+   = note: late-bound region is '_#3r
    = note: number of external vids: 4
    = note: where '_#1r: '_#2r
 
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
index 9605677740f31..3f8ed324f564a 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
@@ -10,8 +10,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
-   = note: late-bound region ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a)) is '_#3r
-   = note: late-bound region ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:18), T)) is '_#4r
+   = note: late-bound region is '_#3r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:42:1
@@ -42,7 +41,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: late-bound region ReFree(DefId(0/0:9 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]), BrNamed(crate0:DefIndex(1:22), T)) is '_#4r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:50:1
@@ -75,7 +73,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: late-bound region ReFree(DefId(0/0:10 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]), BrNamed(crate0:DefIndex(1:26), T)) is '_#4r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:59:1
@@ -108,7 +105,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: late-bound region ReFree(DefId(0/0:11 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]), BrNamed(crate0:DefIndex(1:30), T)) is '_#4r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:78:1
@@ -140,7 +136,6 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
-   = note: late-bound region ReFree(DefId(0/0:12 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]), BrNamed(crate0:DefIndex(1:33), T)) is '_#3r
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-static-closure.rs:87:1
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 176e45ae09872..19dcb5f93dac3 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
@@ -11,6 +11,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
+   = note: late-bound region is '_#4r
    = note: number of external vids: 5
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#2r)>>::AssocType: '_#3r
 
@@ -212,6 +213,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
+   = note: late-bound region is '_#3r
    = note: number of external vids: 4
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
 
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 1f5edf08957d6..106eaa6a3abe9 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
@@ -36,6 +36,7 @@ LL |     twice(cell, value, |a, b| invoke(a, b));
                i16,
                for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) ()>>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) T))
            ]
+   = note: late-bound region is '_#2r
    = note: number of external vids: 3
    = note: where T: '_#1r
 
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 1b9baf61305d9..f0e86a580b20a 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
@@ -16,6 +16,7 @@ LL | |     })
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#1r ()>, T))
            ]
+   = note: late-bound region is '_#2r
    = note: number of external vids: 3
    = note: where T: '_#1r
 
@@ -106,6 +107,7 @@ LL | |     })
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
+   = note: late-bound region is '_#3r
    = note: number of external vids: 4
    = note: where T: '_#2r