about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-09-07 17:56:23 +0000
committerbors <bors@rust-lang.org>2018-09-07 17:56:23 +0000
commitfc81e36242ddddb7149a0d1ca44ebce7fb9eef8a (patch)
treeae68e6f14d8abcbd05accc9a93bb8d9aa04471fa
parent24ef47bccf487a2f80f71f228d71e35f89c5e1d3 (diff)
parentb1211e870370cac1000a64c48ceb8a2ad6dc1f45 (diff)
downloadrust-fc81e36242ddddb7149a0d1ca44ebce7fb9eef8a.tar.gz
rust-fc81e36242ddddb7149a0d1ca44ebce7fb9eef8a.zip
Auto merge of #53327 - wesleywiser:wip_optimize_nll, r=nikomatsakis
[nll] teach SCC about `'static`

r? @nikomatsakis

I think this is right? I am seeing better performance on the `html5ever` benchmark but I'd like a perf run to quantify the exact speedup. There's a few ui tests failing due to changes in the error messages. The main issue seems to be that returns aren't being detected correctly?

`mir_check_cast_unsize.rs` before:

```
error: unsatisfied lifetime constraints
  --> mir_check_cast_unsize.rs:17:46
   |
17 |   fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
   |  ________--____________________________________^
   | |        |
   | |        lifetime `'a` defined here
18 | |     //~^ ERROR unsatisfied lifetime constraints
19 | |     x
20 | |     //~^ WARNING not reporting region error due to nll
21 | | }
   | |_^ return requires that `'a` must outlive `'static`
```

`mir_check_cast_unsize.rs` after:

```
error: unsatisfied lifetime constraints
  --> mir_check_cast_unsize.rs:19:5
   |
17 | fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
   |        -- lifetime `'a` defined here
18 |     //~^ ERROR unsatisfied lifetime constraints
19 |     x
   |     ^ cast requires that `'a` must outlive `'static`
```
-rw-r--r--src/librustc/middle/resolve_lifetime.rs7
-rw-r--r--src/librustc_mir/borrow_check/nll/constraints/graph.rs84
-rw-r--r--src/librustc_mir/borrow_check/nll/constraints/mod.rs3
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs43
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs98
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/mod.rs5
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs3
-rw-r--r--src/librustc_mir/borrow_check/nll/universal_regions.rs38
-rw-r--r--src/test/mir-opt/nll/named-lifetimes-basic.rs2
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr12
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr13
-rw-r--r--src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs3
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr22
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs3
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr24
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr2
-rw-r--r--src/test/ui/nll/mir_check_cast_reify.rs2
-rw-r--r--src/test/ui/nll/mir_check_cast_reify.stderr6
-rw-r--r--src/test/ui/nll/mir_check_cast_unsafe_fn.rs2
-rw-r--r--src/test/ui/nll/mir_check_cast_unsafe_fn.stderr6
-rw-r--r--src/test/ui/nll/mir_check_cast_unsize.stderr2
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr8
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr8
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr10
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs8
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr36
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr2
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr8
-rw-r--r--src/test/ui/regions/regions-addr-of-self.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr18
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-2.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-4.nll.stderr16
-rw-r--r--src/test/ui/regions/regions-static-bound.ll.nll.stderr25
-rw-r--r--src/test/ui/regions/regions-static-bound.ll.stderr2
-rw-r--r--src/test/ui/regions/regions-static-bound.nll.stderr25
-rw-r--r--src/test/ui/regions/regions-static-bound.rs2
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr2
39 files changed, 376 insertions, 190 deletions
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index d0f801e661b..db931d0a739 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2567,6 +2567,13 @@ fn insert_late_bound_lifetimes(
     // - do not appear in the where-clauses
     // - are not implicitly captured by `impl Trait`
     for param in &generics.params {
+        match param.kind {
+            hir::GenericParamKind::Lifetime { .. } => { /* fall through */ }
+
+            // Types are not late-bound.
+            hir::GenericParamKind::Type { .. } => continue,
+        }
+
         let lt_name = hir::LifetimeName::Param(param.name.modern());
         // appears in the where clauses? early-bound.
         if appears_in_where_clause.regions.contains(&lt_name) {
diff --git a/src/librustc_mir/borrow_check/nll/constraints/graph.rs b/src/librustc_mir/borrow_check/nll/constraints/graph.rs
index 1a1094b570b..b1e8b974379 100644
--- a/src/librustc_mir/borrow_check/nll/constraints/graph.rs
+++ b/src/librustc_mir/borrow_check/nll/constraints/graph.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use borrow_check::nll::type_check::Locations;
 use borrow_check::nll::constraints::{ConstraintIndex, ConstraintSet, OutlivesConstraint};
 use rustc::ty::RegionVid;
 use rustc_data_structures::graph;
@@ -31,6 +32,7 @@ crate type ReverseConstraintGraph = ConstraintGraph<Reverse>;
 crate trait ConstraintGraphDirecton: Copy + 'static {
     fn start_region(c: &OutlivesConstraint) -> RegionVid;
     fn end_region(c: &OutlivesConstraint) -> RegionVid;
+    fn is_normal() -> bool;
 }
 
 /// In normal mode, a `R1: R2` constraint results in an edge `R1 ->
@@ -48,6 +50,10 @@ impl ConstraintGraphDirecton for Normal {
     fn end_region(c: &OutlivesConstraint) -> RegionVid {
         c.sub
     }
+
+    fn is_normal() -> bool {
+        true
+    }
 }
 
 /// In reverse mode, a `R1: R2` constraint results in an edge `R2 ->
@@ -65,6 +71,10 @@ impl ConstraintGraphDirecton for Reverse {
     fn end_region(c: &OutlivesConstraint) -> RegionVid {
         c.sup
     }
+
+    fn is_normal() -> bool {
+        false
+    }
 }
 
 impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
@@ -98,32 +108,74 @@ impl<D: ConstraintGraphDirecton> ConstraintGraph<D> {
     /// Given the constraint set from which this graph was built
     /// creates a region graph so that you can iterate over *regions*
     /// and not constraints.
-    crate fn region_graph<'rg>(&'rg self, set: &'rg ConstraintSet) -> RegionGraph<'rg, D> {
-        RegionGraph::new(set, self)
+    crate fn region_graph<'rg>(
+        &'rg self,
+        set: &'rg ConstraintSet,
+        static_region: RegionVid,
+    ) -> RegionGraph<'rg, D> {
+        RegionGraph::new(set, self, static_region)
     }
 
     /// Given a region `R`, iterate over all constraints `R: R1`.
-    crate fn outgoing_edges(&self, region_sup: RegionVid) -> Edges<'_, D> {
-        let first = self.first_constraints[region_sup];
-        Edges {
-            graph: self,
-            pointer: first,
+    crate fn outgoing_edges<'a>(
+        &'a self,
+        region_sup: RegionVid,
+        constraints: &'a ConstraintSet,
+        static_region: RegionVid,
+    ) -> Edges<'a, D> {
+        //if this is the `'static` region and the graph's direction is normal,
+        //then setup the Edges iterator to return all regions #53178
+        if region_sup == static_region && D::is_normal() {
+            Edges {
+                graph: self,
+                constraints,
+                pointer: None,
+                next_static_idx: Some(0),
+                static_region,
+            }
+        } else {
+            //otherwise, just setup the iterator as normal
+            let first = self.first_constraints[region_sup];
+            Edges {
+                graph: self,
+                constraints,
+                pointer: first,
+                next_static_idx: None,
+                static_region,
+           }
         }
     }
 }
 
 crate struct Edges<'s, D: ConstraintGraphDirecton> {
     graph: &'s ConstraintGraph<D>,
+    constraints: &'s ConstraintSet,
     pointer: Option<ConstraintIndex>,
+    next_static_idx: Option<usize>,
+    static_region: RegionVid,
 }
 
 impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
-    type Item = ConstraintIndex;
+    type Item = OutlivesConstraint;
 
     fn next(&mut self) -> Option<Self::Item> {
         if let Some(p) = self.pointer {
             self.pointer = self.graph.next_constraints[p];
-            Some(p)
+
+            Some(self.constraints[p])
+        } else if let Some(next_static_idx) = self.next_static_idx {
+            self.next_static_idx =
+                if next_static_idx == (self.graph.first_constraints.len() - 1) {
+                    None
+                } else {
+                    Some(next_static_idx + 1)
+                };
+
+            Some(OutlivesConstraint {
+                sup: self.static_region,
+                sub: next_static_idx.into(),
+                locations: Locations::All,
+            })
         } else {
             None
         }
@@ -136,6 +188,7 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Edges<'s, D> {
 crate struct RegionGraph<'s, D: ConstraintGraphDirecton> {
     set: &'s ConstraintSet,
     constraint_graph: &'s ConstraintGraph<D>,
+    static_region: RegionVid,
 }
 
 impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> {
@@ -143,10 +196,15 @@ impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> {
     /// R2` is treated as an edge `R1 -> R2`. We use this graph to
     /// construct SCCs for region inference but also for error
     /// reporting.
-    crate fn new(set: &'s ConstraintSet, constraint_graph: &'s ConstraintGraph<D>) -> Self {
+    crate fn new(
+        set: &'s ConstraintSet,
+        constraint_graph: &'s ConstraintGraph<D>,
+        static_region: RegionVid,
+    ) -> Self {
         Self {
             set,
             constraint_graph,
+            static_region,
         }
     }
 
@@ -154,14 +212,12 @@ impl<'s, D: ConstraintGraphDirecton> RegionGraph<'s, D> {
     /// there exists a constraint `R: R1`.
     crate fn outgoing_regions(&self, region_sup: RegionVid) -> Successors<'_, D> {
         Successors {
-            set: self.set,
-            edges: self.constraint_graph.outgoing_edges(region_sup),
+            edges: self.constraint_graph.outgoing_edges(region_sup, self.set, self.static_region),
         }
     }
 }
 
 crate struct Successors<'s, D: ConstraintGraphDirecton> {
-    set: &'s ConstraintSet,
     edges: Edges<'s, D>,
 }
 
@@ -169,7 +225,7 @@ impl<'s, D: ConstraintGraphDirecton> Iterator for Successors<'s, D> {
     type Item = RegionVid;
 
     fn next(&mut self) -> Option<Self::Item> {
-        self.edges.next().map(|c| D::end_region(&self.set[c]))
+        self.edges.next().map(|c| D::end_region(&c))
     }
 }
 
diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs
index 4cb92262ff0..9a8b0f391de 100644
--- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs
@@ -58,8 +58,9 @@ impl ConstraintSet {
     crate fn compute_sccs(
         &self,
         constraint_graph: &graph::NormalConstraintGraph,
+        static_region: RegionVid,
     ) -> Sccs<RegionVid, ConstraintSccIndex> {
-        let region_graph = &constraint_graph.region_graph(self);
+        let region_graph = &constraint_graph.region_graph(self, static_region);
         Sccs::new(region_graph)
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
index ca208a43431..0b9b9b33b3f 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use borrow_check::nll::region_infer::{ConstraintIndex, RegionInferenceContext};
+use borrow_check::nll::constraints::OutlivesConstraint;
+use borrow_check::nll::region_infer::RegionInferenceContext;
 use borrow_check::nll::type_check::Locations;
 use rustc::hir::def_id::DefId;
 use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
@@ -53,7 +54,7 @@ impl fmt::Display for ConstraintCategory {
 #[derive(Copy, Clone, PartialEq, Eq)]
 enum Trace {
     StartRegion,
-    FromConstraint(ConstraintIndex),
+    FromOutlivesConstraint(OutlivesConstraint),
     NotVisited,
 }
 
@@ -80,12 +81,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         debug!(
             "best_blame_constraint: path={:#?}",
             path.iter()
-                .map(|&ci| format!(
-                    "{:?}: {:?} ({:?}: {:?})",
-                    ci,
-                    &self.constraints[ci],
-                    self.constraint_sccs.scc(self.constraints[ci].sup),
-                    self.constraint_sccs.scc(self.constraints[ci].sub),
+                .map(|&c| format!(
+                    "{:?} ({:?}: {:?})",
+                    c,
+                    self.constraint_sccs.scc(c.sup),
+                    self.constraint_sccs.scc(c.sub),
                 ))
                 .collect::<Vec<_>>()
         );
@@ -121,7 +121,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // highlight (e.g., a call site or something).
         let target_scc = self.constraint_sccs.scc(target_region);
         let best_choice = (0..path.len()).rev().find(|&i| {
-            let constraint = &self.constraints[path[i]];
+            let constraint = path[i];
 
             let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup);
 
@@ -164,7 +164,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         &self,
         from_region: RegionVid,
         target_test: impl Fn(RegionVid) -> bool,
-    ) -> Option<(Vec<ConstraintIndex>, RegionVid)> {
+    ) -> Option<(Vec<OutlivesConstraint>, RegionVid)> {
         let mut context = IndexVec::from_elem(Trace::NotVisited, &self.definitions);
         context[from_region] = Trace::StartRegion;
 
@@ -185,9 +185,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                         Trace::NotVisited => {
                             bug!("found unvisited region {:?} on path to {:?}", p, r)
                         }
-                        Trace::FromConstraint(c) => {
+                        Trace::FromOutlivesConstraint(c) => {
                             result.push(c);
-                            p = self.constraints[c].sup;
+                            p = c.sup;
                         }
 
                         Trace::StartRegion => {
@@ -201,11 +201,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             // Otherwise, walk over the outgoing constraints and
             // enqueue any regions we find, keeping track of how we
             // reached them.
-            for constraint in self.constraint_graph.outgoing_edges(r) {
-                assert_eq!(self.constraints[constraint].sup, r);
-                let sub_region = self.constraints[constraint].sub;
+            let fr_static = self.universal_regions.fr_static;
+            for constraint in self.constraint_graph.outgoing_edges(r,
+                                                                   &self.constraints,
+                                                                   fr_static) {
+                assert_eq!(constraint.sup, r);
+                let sub_region = constraint.sub;
                 if let Trace::NotVisited = context[sub_region] {
-                    context[sub_region] = Trace::FromConstraint(constraint);
+                    context[sub_region] = Trace::FromOutlivesConstraint(constraint);
                     deque.push_back(sub_region);
                 }
             }
@@ -216,8 +219,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
     /// This function will return true if a constraint is interesting and false if a constraint
     /// is not. It is useful in filtering constraint paths to only interesting points.
-    fn constraint_is_interesting(&self, index: ConstraintIndex) -> bool {
-        let constraint = self.constraints[index];
+    fn constraint_is_interesting(&self, constraint: OutlivesConstraint) -> bool {
         debug!(
             "constraint_is_interesting: locations={:?} constraint={:?}",
             constraint.locations, constraint
@@ -232,11 +234,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// This function classifies a constraint from a location.
     fn classify_constraint(
         &self,
-        index: ConstraintIndex,
+        constraint: OutlivesConstraint,
         mir: &Mir<'tcx>,
         tcx: TyCtxt<'_, '_, 'tcx>,
     ) -> (ConstraintCategory, Span) {
-        let constraint = self.constraints[index];
         debug!("classify_constraint: constraint={:?}", constraint);
         let span = constraint.locations.span(mir);
         let location = constraint
@@ -244,7 +245,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             .from_location()
             .unwrap_or(Location::START);
 
-        if !self.constraint_is_interesting(index) {
+        if !self.constraint_is_interesting(constraint) {
             return (ConstraintCategory::Boring, span);
         }
 
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index 6177194ab91..5ae123bdc18 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 use borrow_check::nll::region_infer::RegionInferenceContext;
-use borrow_check::nll::ToRegionVid;
 use borrow_check::nll::universal_regions::DefiningTy;
+use borrow_check::nll::ToRegionVid;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::infer::InferCtxt;
@@ -62,20 +62,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         assert!(self.universal_regions.is_universal_region(fr));
 
-        self.give_name_from_error_region(infcx.tcx, mir_def_id, fr, counter, diag)
+        let value = self.give_name_from_error_region(infcx.tcx, mir_def_id, fr, counter, diag)
             .or_else(|| {
                 self.give_name_if_anonymous_region_appears_in_arguments(
-                    infcx, mir, mir_def_id, fr, counter, diag)
+                    infcx, mir, mir_def_id, fr, counter, diag,
+                )
             })
             .or_else(|| {
                 self.give_name_if_anonymous_region_appears_in_upvars(
-                    infcx.tcx, mir, fr, counter, diag)
+                    infcx.tcx, mir, fr, counter, diag,
+                )
             })
             .or_else(|| {
                 self.give_name_if_anonymous_region_appears_in_output(
-                    infcx, mir, mir_def_id, fr, counter, diag)
+                    infcx, mir, mir_def_id, fr, counter, diag,
+                )
             })
-            .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr))
+            .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr));
+
+        debug!("give_region_a_name: gave name {:?}", value);
+        value
     }
 
     /// Check for the case where `fr` maps to something that the
@@ -101,7 +107,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 } else {
                     None
                 }
-            },
+            }
 
             ty::ReStatic => Some(keywords::StaticLifetime.name().as_interned_str()),
 
@@ -109,15 +115,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 ty::BoundRegion::BrNamed(_, name) => {
                     self.highlight_named_span(tcx, error_region, &name, diag);
                     Some(name)
-                },
+                }
 
                 ty::BoundRegion::BrEnv => {
                     let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir");
                     let def_ty = self.universal_regions.defining_ty;
 
                     if let DefiningTy::Closure(def_id, substs) = def_ty {
-                        let args_span = if let hir::ExprKind::Closure(_, _, _, span, _)
-                            = tcx.hir.expect_expr(mir_node_id).node
+                        let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) =
+                            tcx.hir.expect_expr(mir_node_id).node
                         {
                             span
                         } else {
@@ -195,16 +201,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let node = tcx.hir.as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID);
 
         let mut sp = cm.def_span(tcx.hir.span(node));
-        if let Some(param) = tcx.hir.get_generics(scope).and_then(|generics| {
-            generics.get_named(name)
-        }) {
+        if let Some(param) = tcx.hir
+            .get_generics(scope)
+            .and_then(|generics| generics.get_named(name))
+        {
             sp = param.span;
         }
 
-        diag.span_label(
-            sp,
-            format!("lifetime `{}` defined here", name),
-        );
+        diag.span_label(sp, format!("lifetime `{}` defined here", name));
     }
 
     /// Find an argument that contains `fr` and label it with a fully
@@ -242,14 +246,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             return Some(region_name);
         }
 
-        self.give_name_if_we_cannot_match_hir_ty(
-            infcx,
-            mir,
-            fr,
-            arg_ty,
-            counter,
-            diag,
-        )
+        self.give_name_if_we_cannot_match_hir_ty(infcx, mir, fr, arg_ty, counter, diag)
     }
 
     fn give_name_if_we_can_match_hir_ty_from_argument(
@@ -314,8 +311,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             infcx.extract_type_name(&argument_ty)
         });
 
-        debug!("give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
-               type_name, needle_fr);
+        debug!(
+            "give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
+            type_name, needle_fr
+        );
         let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() {
             // Only add a label if we can confirm that a region was labelled.
             let argument_index = self.get_argument_index_for_region(infcx.tcx, needle_fr)?;
@@ -547,13 +546,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         diag: &mut DiagnosticBuilder<'_>,
     ) -> Option<InternedString> {
         let upvar_index = self.get_upvar_index_for_region(tcx, fr)?;
-        let (upvar_name, upvar_span) = self.get_upvar_name_and_span_for_region(tcx, mir,
-                                                                               upvar_index);
+        let (upvar_name, upvar_span) =
+            self.get_upvar_name_and_span_for_region(tcx, mir, upvar_index);
         let region_name = self.synthesize_region_name(counter);
 
         diag.span_label(
             upvar_span,
-            format!("lifetime `{}` appears in the type of `{}`", region_name, upvar_name),
+            format!(
+                "lifetime `{}` appears in the type of `{}`",
+                region_name, upvar_name
+            ),
         );
 
         Some(region_name)
@@ -579,27 +581,33 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             "give_name_if_anonymous_region_appears_in_output: return_ty = {:?}",
             return_ty
         );
-        if !infcx.tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) {
+        if !infcx
+            .tcx
+            .any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr)
+        {
             return None;
         }
 
-        let type_name = with_highlight_region(fr, *counter, || {
-            infcx.extract_type_name(&return_ty)
-        });
+        let type_name = with_highlight_region(fr, *counter, || infcx.extract_type_name(&return_ty));
 
         let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir");
 
-        let (return_span, mir_description) = if let hir::ExprKind::Closure(_, _, _, span, gen_move)
-            = tcx.hir.expect_expr(mir_node_id).node
-        {
-            (
-                tcx.sess.source_map().end_point(span),
-                if gen_move.is_some() { " of generator" } else { " of closure" }
-            )
-        } else {
-            // unreachable?
-            (mir.span, "")
-        };
+        let (return_span, mir_description) =
+            if let hir::ExprKind::Closure(_, _, _, span, gen_move) =
+                tcx.hir.expect_expr(mir_node_id).node
+            {
+                (
+                    tcx.sess.source_map().end_point(span),
+                    if gen_move.is_some() {
+                        " of generator"
+                    } else {
+                        " of closure"
+                    },
+                )
+            } else {
+                // unreachable?
+                (mir.span, "")
+            };
 
         diag.span_label(
             return_span,
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 ff68b5987e8..bbdf2a92922 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -11,7 +11,7 @@
 use super::universal_regions::UniversalRegions;
 use borrow_check::nll::constraints::graph::NormalConstraintGraph;
 use borrow_check::nll::constraints::{
-    ConstraintIndex, ConstraintSccIndex, ConstraintSet, OutlivesConstraint,
+    ConstraintSccIndex, ConstraintSet, OutlivesConstraint,
 };
 use borrow_check::nll::region_infer::values::{RegionElement, ToElementIndex};
 use borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations;
@@ -234,7 +234,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         let constraints = Rc::new(outlives_constraints); // freeze constraints
         let constraint_graph = Rc::new(constraints.graph(definitions.len()));
-        let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph));
+        let fr_static = universal_regions.fr_static;
+        let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static));
 
         let mut scc_values = RegionValues::new(elements, universal_regions.len(), max_universe);
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
index b3fc73e9b7b..357e9ee7210 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
@@ -69,7 +69,8 @@ fn regions_that_outlive_free_regions(
     // reachable from each free region, we will have all the
     // regions that are forced to outlive some free region.
     let rev_constraint_graph = constraint_set.reverse_graph(num_region_vars);
-    let rev_region_graph = rev_constraint_graph.region_graph(constraint_set);
+    let fr_static = universal_regions.fr_static;
+    let rev_region_graph = rev_constraint_graph.region_graph(constraint_set, fr_static);
 
     // Stack for the depth-first search. Start out with all the free regions.
     let mut stack: Vec<_> = universal_regions.universal_regions().collect();
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index 8112b71b127..51153128256 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -241,8 +241,9 @@ impl<'tcx> UniversalRegions<'tcx> {
             region_mapping.push(fr);
         });
 
-        for_each_late_bound_region_defined_on(
-            tcx, closure_base_def_id, |r| { region_mapping.push(r); });
+        for_each_late_bound_region_defined_on(tcx, closure_base_def_id, |r| {
+            region_mapping.push(r);
+        });
 
         assert_eq!(
             region_mapping.len(),
@@ -352,9 +353,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
         //     let c = || { let x: &'a u32 = ...; }
         // }
         if self.mir_def_id != closure_base_def_id {
-            self.infcx.replace_late_bound_regions_with_nll_infer_vars(
-                self.mir_def_id,
-                &mut indices)
+            self.infcx
+                .replace_late_bound_regions_with_nll_infer_vars(self.mir_def_id, &mut indices)
         }
 
         let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
@@ -371,9 +371,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
         // Converse of above, if this is a function then the late-bound regions declared on its
         // signature are local to the fn.
         if self.mir_def_id == closure_base_def_id {
-            self.infcx.replace_late_bound_regions_with_nll_infer_vars(
-                self.mir_def_id,
-                &mut indices);
+            self.infcx
+                .replace_late_bound_regions_with_nll_infer_vars(self.mir_def_id, &mut indices);
         }
 
         let fr_fn_body = self.infcx.next_nll_region_var(FR).to_region_vid();
@@ -582,11 +581,10 @@ trait InferCtxtExt<'tcx> {
     where
         T: TypeFoldable<'tcx>;
 
-
     fn replace_late_bound_regions_with_nll_infer_vars(
         &self,
         mir_def_id: DefId,
-        indices: &mut UniversalRegionIndices<'tcx>
+        indices: &mut UniversalRegionIndices<'tcx>,
     );
 }
 
@@ -619,6 +617,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'gcx, 'tcx> {
             value, all_outlive_scope,
         );
         let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
+            debug!("replace_bound_regions_with_nll_infer_vars: br={:?}", br);
             let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
                 scope: all_outlive_scope,
                 bound_region: br,
@@ -626,7 +625,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'gcx, 'tcx> {
             let region_vid = self.next_nll_region_var(origin);
             indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid());
             debug!(
-                "liberated_region={:?} => {:?}",
+                "replace_bound_regions_with_nll_infer_vars: liberated_region={:?} => {:?}",
                 liberated_region, region_vid
             );
             region_vid
@@ -648,12 +647,18 @@ impl<'cx, 'gcx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'gcx, 'tcx> {
         mir_def_id: DefId,
         indices: &mut UniversalRegionIndices<'tcx>,
     ) {
+        debug!(
+            "replace_late_bound_regions_with_nll_infer_vars(mir_def_id={:?})",
+            mir_def_id
+        );
         let closure_base_def_id = self.tcx.closure_base_def_id(mir_def_id);
         for_each_late_bound_region_defined_on(self.tcx, closure_base_def_id, |r| {
+            debug!("replace_late_bound_regions_with_nll_infer_vars: r={:?}", r);
             if !indices.indices.contains_key(&r) {
                 let region_vid = self.next_nll_region_var(FR);
                 indices.insert_late_bound_region(r, region_vid.to_region_vid());
-            }});
+            }
+        });
     }
 }
 
@@ -703,11 +708,14 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
 fn for_each_late_bound_region_defined_on<'tcx>(
     tcx: TyCtxt<'_, '_, 'tcx>,
     fn_def_id: DefId,
-    mut f: impl FnMut(ty::Region<'tcx>)
-    ) {
+    mut f: impl FnMut(ty::Region<'tcx>),
+) {
     if let Some(late_bounds) = tcx.is_late_bound_map(fn_def_id.index) {
         for late_bound in late_bounds.iter() {
-            let hir_id = HirId{ owner: fn_def_id.index, local_id: *late_bound };
+            let hir_id = HirId {
+                owner: fn_def_id.index,
+                local_id: *late_bound,
+            };
             let region_node_id = tcx.hir.hir_to_node_id(hir_id);
             let name = tcx.hir.name(region_node_id).as_interned_str();
             let region_def_id = tcx.hir.local_def_id(region_node_id);
diff --git a/src/test/mir-opt/nll/named-lifetimes-basic.rs b/src/test/mir-opt/nll/named-lifetimes-basic.rs
index ffc5603bb16..c7fa7973a2d 100644
--- a/src/test/mir-opt/nll/named-lifetimes-basic.rs
+++ b/src/test/mir-opt/nll/named-lifetimes-basic.rs
@@ -34,7 +34,7 @@ fn main() {
 // | '_#4r    | Local    | ['_#4r]
 // |
 // | Inferred Region Values
-// | '_#0r    | U0 | {bb0[0..=1], '_#0r}
+// | '_#0r    | U0 | {bb0[0..=1], '_#0r, '_#1r, '_#2r, '_#3r, '_#4r}
 // | '_#1r    | U0 | {bb0[0..=1], '_#1r}
 // | '_#2r    | U0 | {bb0[0..=1], '_#2r}
 // | '_#3r    | U0 | {bb0[0..=1], '_#3r}
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr
index b5cba945fb1..2f632fec17e 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.nll.stderr
@@ -6,5 +6,15 @@ LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
 LL |    bar(foo, x) //[transmute]~ ERROR E0495
    |    ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
 
-error: aborting due to previous error
+error: unsatisfied lifetime constraints
+  --> $DIR/project-fn-ret-contravariant.rs:48:4
+   |
+LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
+   |        -- -- lifetime `'b` defined here
+   |        |
+   |        lifetime `'a` defined here
+LL |    bar(foo, x) //[transmute]~ ERROR E0495
+   |    ^^^^^^^^^^^ requires that `'a` must outlive `'b`
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr
index bb1be40980d..63e1f665005 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.nll.stderr
@@ -7,5 +7,16 @@ LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
 LL |    bar(foo, x) //[transmute]~ ERROR E0495
    |    ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
 
-error: aborting due to previous error
+error: unsatisfied lifetime constraints
+  --> $DIR/project-fn-ret-invariant.rs:58:13
+   |
+LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
+   |        -- -- lifetime `'b` defined here
+   |        |
+   |        lifetime `'a` defined here
+...
+LL |    bar(foo, x) //[transmute]~ ERROR E0495
+   |             ^ requires that `'a` must outlive `'b`
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
index 2568eb2ed3f..d75de81fc1c 100644
--- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
+++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
@@ -4,7 +4,7 @@ error: unsatisfied lifetime constraints
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
    |                         - let's call the lifetime of this reference `'1`
 LL |         self.x.iter().map(|a| a.0)
-   |         ^^^^^^^^^^^^^ requires that `'1` must outlive `'static`
+   |         ^^^^^^ cast requires that `'1` must outlive `'static`
 
 error: unsatisfied lifetime constraints
   --> $DIR/static-return-lifetime-infered.rs:21:9
@@ -12,7 +12,7 @@ error: unsatisfied lifetime constraints
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
    |                    -- lifetime `'a` defined here
 LL |         self.x.iter().map(|a| a.0)
-   |         ^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+   |         ^^^^^^ cast requires that `'a` must outlive `'static`
 
 error: aborting due to 2 previous errors
 
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 e32a4395f88..9963954c9c2 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
@@ -43,7 +43,8 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3
 #[rustc_regions]
 fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-        //~^ ERROR
+        //~^ ERROR borrowed data escapes outside of function
+        //~| ERROR unsatisfied lifetime constraints
 
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
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 0d479356304..f50864d946b 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
@@ -3,7 +3,8 @@ note: External requirements
    |
 LL |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
    |  _______________________________________________^
-LL | |         //~^ ERROR
+LL | |         //~^ ERROR borrowed data escapes outside of function
+LL | |         //~| ERROR unsatisfied lifetime constraints
 LL | |
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
@@ -22,8 +23,8 @@ note: No external requirements
    |
 LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
 LL | |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-LL | |         //~^ ERROR
-LL | |
+LL | |         //~^ ERROR borrowed data escapes outside of function
+LL | |         //~| ERROR unsatisfied lifetime constraints
 ...  |
 LL | |     });
 LL | | }
@@ -37,12 +38,23 @@ error: borrowed data escapes outside of function
 LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
    |                     ------ `cell_a` is a reference that is only valid in the function body
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-LL | |         //~^ ERROR
+LL | |         //~^ ERROR borrowed data escapes outside of function
+LL | |         //~| ERROR unsatisfied lifetime constraints
 LL | |
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |     });
    | |______^ `cell_a` escapes the function body here
 
-error: aborting due to previous error
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:29
+   |
+LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+   |           --  -- lifetime `'b` defined here
+   |           |
+   |           lifetime `'a` defined here
+LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
+   |                             ^^^^^^^ requires that `'a` must outlive `'b`
+
+error: aborting due to 2 previous errors
 
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 0334f9ffd86..d35b5c34a91 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
@@ -46,7 +46,8 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3
 #[rustc_regions]
 fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-        //~^ ERROR
+        //~^ ERROR borrowed data escapes outside of function
+        //~| ERROR unsatisfied lifetime constraints
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
     });
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 88743169fcb..8a89320d10c 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
@@ -3,7 +3,8 @@ note: External requirements
    |
 LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
    |  _______________________________________________^
-LL | |         //~^ ERROR
+LL | |         //~^ ERROR borrowed data escapes outside of function
+LL | |         //~| ERROR unsatisfied lifetime constraints
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |     });
@@ -21,9 +22,9 @@ note: No external requirements
    |
 LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
 LL | |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | |         //~^ ERROR
-LL | |         // Only works if 'x: 'y:
-LL | |         demand_y(x, y, x.get())
+LL | |         //~^ ERROR borrowed data escapes outside of function
+LL | |         //~| ERROR unsatisfied lifetime constraints
+...  |
 LL | |     });
 LL | | }
    | |_^
@@ -36,11 +37,22 @@ error: borrowed data escapes outside of function
 LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
    |                     ------ `cell_a` is a reference that is only valid in the function body
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | |         //~^ ERROR
+LL | |         //~^ ERROR borrowed data escapes outside of function
+LL | |         //~| ERROR unsatisfied lifetime constraints
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |     });
    | |______^ `cell_a` escapes the function body here
 
-error: aborting due to previous error
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:29
+   |
+LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
+   |           --  -- lifetime `'b` defined here
+   |           |
+   |           lifetime `'a` defined here
+LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
+   |                             ^^^^^^^ requires that `'a` must outlive `'b`
+
+error: aborting due to 2 previous errors
 
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 fda9743fb6b..d1976b40df4 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
@@ -17,7 +17,7 @@ LL | |     });
                i32,
                extern "rust-call" fn((T,))
            ]
-   = note: number of external vids: 3
+   = note: number of external vids: 2
    = note: where T: '_#1r
 
 note: No external requirements
diff --git a/src/test/ui/nll/mir_check_cast_reify.rs b/src/test/ui/nll/mir_check_cast_reify.rs
index 93f10b96c22..332ec7a7da2 100644
--- a/src/test/ui/nll/mir_check_cast_reify.rs
+++ b/src/test/ui/nll/mir_check_cast_reify.rs
@@ -44,8 +44,8 @@ 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;
+    //~^ ERROR unsatisfied lifetime constraints
     f(x)
-    //~^ ERROR
 }
 
 fn main() {}
diff --git a/src/test/ui/nll/mir_check_cast_reify.stderr b/src/test/ui/nll/mir_check_cast_reify.stderr
index fdb71b17287..fa5c4100c91 100644
--- a/src/test/ui/nll/mir_check_cast_reify.stderr
+++ b/src/test/ui/nll/mir_check_cast_reify.stderr
@@ -1,11 +1,11 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/mir_check_cast_reify.rs:47:5
+  --> $DIR/mir_check_cast_reify.rs:46:25
    |
 LL | fn bar<'a>(x: &'a u32) -> &'static u32 {
    |        -- lifetime `'a` defined here
 ...
-LL |     f(x)
-   |     ^^^^ returning this value requires that `'a` must outlive `'static`
+LL |     let f: fn(_) -> _ = foo;
+   |                         ^^^ cast requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/mir_check_cast_unsafe_fn.rs b/src/test/ui/nll/mir_check_cast_unsafe_fn.rs
index 71dcfc8886c..937ab31c315 100644
--- a/src/test/ui/nll/mir_check_cast_unsafe_fn.rs
+++ b/src/test/ui/nll/mir_check_cast_unsafe_fn.rs
@@ -16,8 +16,8 @@ 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;
+    //~^ ERROR unsatisfied lifetime constraints
     unsafe { g(input) }
-    //~^ ERROR
 }
 
 fn main() {}
diff --git a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr
index c14fb93a525..82ff71c0551 100644
--- a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr
+++ b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr
@@ -1,11 +1,11 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/mir_check_cast_unsafe_fn.rs:19:14
+  --> $DIR/mir_check_cast_unsafe_fn.rs:18:32
    |
 LL | fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
    |        -- lifetime `'a` defined here
 ...
-LL |     unsafe { g(input) }
-   |              ^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+LL |     let g: unsafe fn(_) -> _ = f;
+   |                                ^ cast requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/mir_check_cast_unsize.stderr b/src/test/ui/nll/mir_check_cast_unsize.stderr
index 526dfb60133..77a2e8311f0 100644
--- a/src/test/ui/nll/mir_check_cast_unsize.stderr
+++ b/src/test/ui/nll/mir_check_cast_unsize.stderr
@@ -4,7 +4,7 @@ error: unsatisfied lifetime constraints
 LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
    |        -- lifetime `'a` defined here
 LL |     x
-   |     ^ returning this value requires that `'a` must outlive `'static`
+   |     ^ cast requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
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 61e9794b76e..9b7fe466696 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
@@ -10,7 +10,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                i32,
                extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>
            ]
-   = note: number of external vids: 4
+   = note: number of external vids: 3
    = note: where <T as std::iter::Iterator>::Item: '_#2r
 
 note: No external requirements
@@ -50,7 +50,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                i32,
                extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>
            ]
-   = note: number of external vids: 4
+   = note: number of external vids: 3
    = note: where <T as std::iter::Iterator>::Item: '_#2r
 
 note: No external requirements
@@ -82,7 +82,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                i32,
                extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where <T as std::iter::Iterator>::Item: '_#3r
 
 note: No external requirements
@@ -124,7 +124,7 @@ LL |     with_signature(x, |mut y| Box::new(y.next()))
                i32,
                extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where <T as std::iter::Iterator>::Item: '_#3r
 
 note: No external requirements
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 918cf53cf36..24f4bea1ba2 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,7 +10,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where T: '_#2r
    = note: where '_#1r: '_#2r
 
@@ -63,7 +63,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where T: '_#3r
    = note: where '_#2r: '_#3r
 
@@ -117,7 +117,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where T: '_#3r
    = note: where '_#2r: '_#3r
 
@@ -171,7 +171,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where T: '_#3r
    = note: where '_#2r: '_#3r
 
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 ab1ad42f2a9..df4f619b776 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,7 +10,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where '_#1r: '_#2r
 
 note: No external requirements
@@ -54,7 +54,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where '_#2r: '_#3r
 
 note: No external requirements
@@ -99,7 +99,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where '_#2r: '_#3r
 
 note: No external requirements
@@ -144,7 +144,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where '_#2r: '_#3r
 
 note: No external requirements
@@ -177,7 +177,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
-   = note: number of external vids: 4
+   = note: number of external vids: 3
    = note: where '_#1r: '_#2r
 
 note: No external requirements
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 72c1a631396..b4925253524 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
@@ -46,7 +46,7 @@ where
     T: Anything<'b, 'c>,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ ERROR associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
+    //~^ ERROR associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may not live long enough
 }
 
 #[rustc_regions]
@@ -56,7 +56,7 @@ where
     'a: 'a,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ ERROR associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
+    //~^ ERROR associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
 }
 
 #[rustc_regions]
@@ -76,7 +76,7 @@ where
     // can do better here with a more involved verification step.
 
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ ERROR associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
+    //~^ ERROR associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
 }
 
 #[rustc_regions]
@@ -103,7 +103,7 @@ where
     T: Anything<'b, 'b>,
 {
     with_signature(cell, t, |cell, t| require(cell, t));
-    //~^ ERROR
+    //~^ ERROR unsatisfied lifetime constraints
 }
 
 #[rustc_regions]
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 9cabd29b12d..176e45ae098 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,7 +11,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: number of external vids: 6
+   = note: number of external vids: 5
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#2r)>>::AssocType: '_#3r
 
 note: No external requirements
@@ -22,7 +22,7 @@ LL | | where
 LL | |     T: Anything<'b, 'c>,
 LL | | {
 LL | |     with_signature(cell, t, |cell, t| require(cell, t));
-LL | |     //~^ ERROR associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
+LL | |     //~^ ERROR associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may not live long enough
 LL | | }
    | |_^
    |
@@ -32,13 +32,13 @@ LL | | }
                T
            ]
 
-error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
+error[E0309]: the associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may not live long enough
   --> $DIR/projection-two-region-trait-bound-closure.rs:48:29
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding an explicit lifetime bound `<T as Anything<'_#6r, '_#7r>>::AssocType: ReFree(DefId(0/0:8 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:18), 'a))`...
+   = help: consider adding an explicit lifetime bound `<T as Anything<'_#5r, '_#6r>>::AssocType: ReFree(DefId(0/0:8 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:18), 'a))`...
 
 note: External requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:58:29
@@ -54,7 +54,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
            ]
-   = note: number of external vids: 6
+   = note: number of external vids: 5
    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
 
 note: No external requirements
@@ -65,7 +65,7 @@ LL | | where
 LL | |     T: Anything<'b, 'c>,
 LL | |     'a: 'a,
 ...  |
-LL | |     //~^ ERROR associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
+LL | |     //~^ ERROR associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
 LL | | }
    | |_^
    |
@@ -76,13 +76,13 @@ LL | | }
                T
            ]
 
-error[E0309]: the associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
+error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
   --> $DIR/projection-two-region-trait-bound-closure.rs:58:29
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding an explicit lifetime bound `<T as Anything<'_#7r, '_#8r>>::AssocType: ReEarlyBound(0, 'a)`...
+   = help: consider adding an explicit lifetime bound `<T as Anything<'_#6r, '_#7r>>::AssocType: ReEarlyBound(0, 'a)`...
 
 note: External requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:78:29
@@ -98,7 +98,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
            ]
-   = note: number of external vids: 6
+   = note: number of external vids: 5
    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
 
 note: No external requirements
@@ -109,7 +109,7 @@ LL | | where
 LL | |     T: Anything<'b, 'c>,
 LL | |     T::AssocType: 'a,
 ...  |
-LL | |     //~^ ERROR associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
+LL | |     //~^ ERROR associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
 LL | | }
    | |_^
    |
@@ -120,13 +120,13 @@ LL | | }
                T
            ]
 
-error[E0309]: the associated type `<T as Anything<'_#7r, '_#8r>>::AssocType` may not live long enough
+error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough
   --> $DIR/projection-two-region-trait-bound-closure.rs:78:29
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding an explicit lifetime bound `<T as Anything<'_#7r, '_#8r>>::AssocType: ReEarlyBound(0, 'a)`...
+   = help: consider adding an explicit lifetime bound `<T as Anything<'_#6r, '_#7r>>::AssocType: ReEarlyBound(0, 'a)`...
 
 note: External requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:88:29
@@ -142,7 +142,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
            ]
-   = note: number of external vids: 6
+   = note: number of external vids: 5
    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
 
 note: No external requirements
@@ -178,7 +178,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T))
            ]
-   = note: number of external vids: 6
+   = note: number of external vids: 5
    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#3r)>>::AssocType: '_#4r
 
 note: No external requirements
@@ -212,7 +212,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
 
 note: No external requirements
@@ -223,7 +223,7 @@ LL | | where
 LL | |     T: Anything<'b, 'b>,
 LL | | {
 LL | |     with_signature(cell, t, |cell, t| require(cell, t));
-LL | |     //~^ ERROR
+LL | |     //~^ ERROR unsatisfied lifetime constraints
 LL | | }
    | |_^
    |
@@ -256,7 +256,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where <T as Anything<ReClosureBound('_#2r), ReClosureBound('_#2r)>>::AssocType: '_#3r
 
 note: No external requirements
@@ -289,7 +289,7 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
-   = note: number of external vids: 4
+   = note: number of external vids: 3
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
 
 note: No external requirements
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 6050e627c71..1f5edf08957 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
@@ -9,7 +9,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: number of external vids: 3
+   = note: number of external vids: 2
    = note: where T: '_#1r
 
 note: No external requirements
@@ -36,7 +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: number of external vids: 4
+   = note: number of external vids: 3
    = note: where T: '_#1r
 
 note: No external requirements
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 5215f6a5277..9e69ae05173 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
@@ -10,7 +10,7 @@ LL |     with_signature(x, |y| y)
                i32,
                extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn std::fmt::Debug + '_#2r)>
            ]
-   = note: number of external vids: 4
+   = note: number of external vids: 3
    = note: where T: '_#2r
 
 note: No external requirements
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 7129ec397de..1b9baf61305 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,7 +16,7 @@ LL | |     })
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#1r ()>, T))
            ]
-   = note: number of external vids: 4
+   = note: number of external vids: 3
    = note: where T: '_#1r
 
 note: No external requirements
@@ -69,7 +69,7 @@ LL | |     })
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
-   = note: number of external vids: 4
+   = note: number of external vids: 3
    = note: where T: '_#2r
 
 note: No external requirements
@@ -106,7 +106,7 @@ LL | |     })
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where T: '_#2r
 
 note: No external requirements
@@ -156,7 +156,7 @@ LL | |     })
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T))
            ]
-   = note: number of external vids: 5
+   = note: number of external vids: 4
    = note: where T: '_#3r
 
 note: No external requirements
diff --git a/src/test/ui/regions/regions-addr-of-self.nll.stderr b/src/test/ui/regions/regions-addr-of-self.nll.stderr
index 18578a18134..a85822e48fa 100644
--- a/src/test/ui/regions/regions-addr-of-self.nll.stderr
+++ b/src/test/ui/regions/regions-addr-of-self.nll.stderr
@@ -1,10 +1,10 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-self.rs:17:37
+  --> $DIR/regions-addr-of-self.rs:17:13
    |
 LL |     pub fn chase_cat(&mut self) {
    |                      - let's call the lifetime of this reference `'1`
 LL |         let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer
-   |                                     ^^^^^^^^^^^^^^^^^^^^^ requires that `'1` must outlive `'static`
+   |             ^ requires that `'1` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr
index d20cf12f416..9d6301af0fb 100644
--- a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr
+++ b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr
@@ -1,10 +1,22 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-addr-of-upvar-self.rs:20:41
+  --> $DIR/regions-addr-of-upvar-self.rs:20:17
    |
 LL |         let _f = || {
    |                  -- lifetime `'1` represents this closure's body
 LL |             let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
-   |                                         ^^^^^^^^^^^^^^ requires that `'1` must outlive `'static`
+   |                 ^ requires that `'1` must outlive `'static`
+   |
+   = note: closure implements `FnMut`, so references to captured variables can't escape the closure
+
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-addr-of-upvar-self.rs:20:17
+   |
+LL |     pub fn chase_cat(&mut self) {
+   |                      --------- lifetime `'2` appears in the type of `self`
+LL |         let _f = || {
+   |                  -- lifetime `'1` represents this closure's body
+LL |             let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
+   |                 ^ requires that `'1` must outlive `'2`
    |
    = note: closure implements `FnMut`, so references to captured variables can't escape the closure
 
@@ -29,6 +41,6 @@ LL |     }
    |
    = note: borrowed value must be valid for the static lifetime...
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr
index c073e3728e7..e619431ddbb 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr
@@ -1,10 +1,10 @@
 error: unsatisfied lifetime constraints
-  --> $DIR/regions-close-object-into-object-2.rs:20:5
+  --> $DIR/regions-close-object-into-object-2.rs:20:11
    |
 LL | fn g<'a, T: 'static>(v: Box<A<T>+'a>) -> Box<X+'static> {
    |      -- lifetime `'a` defined here
 LL |     box B(&*v) as Box<X> //~ ERROR cannot infer
-   |     ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+   |           ^^^ cast requires that `'a` must outlive `'static`
 
 error[E0597]: `*v` does not live long enough
   --> $DIR/regions-close-object-into-object-2.rs:20:11
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr
index 4b47b951d77..1de1cdc9807 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr
@@ -6,14 +6,6 @@ LL |     box B(&*v) as Box<X> //~ ERROR cannot infer
    |
    = help: consider adding an explicit lifetime bound `U: 'static`...
 
-error: unsatisfied lifetime constraints
-  --> $DIR/regions-close-object-into-object-4.rs:20:5
-   |
-LL | fn i<'a, T, U>(v: Box<A<U>+'a>) -> Box<X+'static> {
-   |      -- lifetime `'a` defined here
-LL |     box B(&*v) as Box<X> //~ ERROR cannot infer
-   |     ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
-
 error[E0310]: the parameter type `U` may not live long enough
   --> $DIR/regions-close-object-into-object-4.rs:20:9
    |
@@ -22,6 +14,14 @@ LL |     box B(&*v) as Box<X> //~ ERROR cannot infer
    |
    = help: consider adding an explicit lifetime bound `U: 'static`...
 
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-close-object-into-object-4.rs:20:11
+   |
+LL | fn i<'a, T, U>(v: Box<A<U>+'a>) -> Box<X+'static> {
+   |      -- lifetime `'a` defined here
+LL |     box B(&*v) as Box<X> //~ ERROR cannot infer
+   |           ^^^ cast requires that `'a` must outlive `'static`
+
 error[E0597]: `*v` does not live long enough
   --> $DIR/regions-close-object-into-object-4.rs:20:11
    |
diff --git a/src/test/ui/regions/regions-static-bound.ll.nll.stderr b/src/test/ui/regions/regions-static-bound.ll.nll.stderr
index 462fbe8ee19..dc3a32cec6a 100644
--- a/src/test/ui/regions/regions-static-bound.ll.nll.stderr
+++ b/src/test/ui/regions/regions-static-bound.ll.nll.stderr
@@ -15,7 +15,7 @@ LL |     static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of
    |     ^^^^^^^^^^^^^ lifetime `'static` required
 
 error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/regions-static-bound.rs:26:5
+  --> $DIR/regions-static-bound.rs:27:5
    |
 LL | fn error(u: &(), v: &()) {
    |                     --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()`
@@ -23,6 +23,27 @@ LL | fn error(u: &(), v: &()) {
 LL |     static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
    |     ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
 
-error: aborting due to 3 previous errors
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-static-bound.rs:24:5
+   |
+LL | fn error(u: &(), v: &()) {
+   |             -       - let's call the lifetime of this reference `'2`
+   |             |
+   |             let's call the lifetime of this reference `'1`
+LL |     static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
+   |     ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-static-bound.rs:27:5
+   |
+LL | fn error(u: &(), v: &()) {
+   |             -       - let's call the lifetime of this reference `'1`
+   |             |
+   |             let's call the lifetime of this reference `'2`
+...
+LL |     static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
+   |     ^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/regions/regions-static-bound.ll.stderr b/src/test/ui/regions/regions-static-bound.ll.stderr
index cf291279210..16add00eb41 100644
--- a/src/test/ui/regions/regions-static-bound.ll.stderr
+++ b/src/test/ui/regions/regions-static-bound.ll.stderr
@@ -20,7 +20,7 @@ LL |     static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of
    |     ^^^^^^^^^ lifetime `'static` required
 
 error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/regions-static-bound.rs:26:5
+  --> $DIR/regions-static-bound.rs:27:5
    |
 LL | fn error(u: &(), v: &()) {
    |                     --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()`
diff --git a/src/test/ui/regions/regions-static-bound.nll.stderr b/src/test/ui/regions/regions-static-bound.nll.stderr
index 462fbe8ee19..dc3a32cec6a 100644
--- a/src/test/ui/regions/regions-static-bound.nll.stderr
+++ b/src/test/ui/regions/regions-static-bound.nll.stderr
@@ -15,7 +15,7 @@ LL |     static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of
    |     ^^^^^^^^^^^^^ lifetime `'static` required
 
 error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/regions-static-bound.rs:26:5
+  --> $DIR/regions-static-bound.rs:27:5
    |
 LL | fn error(u: &(), v: &()) {
    |                     --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()`
@@ -23,6 +23,27 @@ LL | fn error(u: &(), v: &()) {
 LL |     static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
    |     ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
 
-error: aborting due to 3 previous errors
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-static-bound.rs:24:5
+   |
+LL | fn error(u: &(), v: &()) {
+   |             -       - let's call the lifetime of this reference `'2`
+   |             |
+   |             let's call the lifetime of this reference `'1`
+LL |     static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
+   |     ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-static-bound.rs:27:5
+   |
+LL | fn error(u: &(), v: &()) {
+   |             -       - let's call the lifetime of this reference `'1`
+   |             |
+   |             let's call the lifetime of this reference `'2`
+...
+LL |     static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
+   |     ^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/regions/regions-static-bound.rs b/src/test/ui/regions/regions-static-bound.rs
index c5dc6000e83..34baf5ffff0 100644
--- a/src/test/ui/regions/regions-static-bound.rs
+++ b/src/test/ui/regions/regions-static-bound.rs
@@ -23,8 +23,10 @@ fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
 fn error(u: &(), v: &()) {
     static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
     //[nll]~^ ERROR explicit lifetime required in the type of `u` [E0621]
+    //[nll]~| ERROR unsatisfied lifetime constraints
     static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
     //[nll]~^ ERROR explicit lifetime required in the type of `v` [E0621]
+    //[nll]~| ERROR unsatisfied lifetime constraints
 }
 
 fn main() {}
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr
index 7adb195b7d0..745c65c54df 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr
@@ -5,7 +5,7 @@ LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
    |                - let's call the lifetime of this reference `'1`
 LL |     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
 LL |     Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
-   |     ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
 
 error: aborting due to previous error