about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-07-03 11:38:09 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-07-04 05:09:33 -0400
commit727f01700b074181bddf49caa07ac5e34455680d (patch)
treea41db880441da4f99cdc24306f02950d3fc05d0a /src
parentfa02d68eecbb3ff253c4e6f2f7dcc171c7c25283 (diff)
downloadrust-727f01700b074181bddf49caa07ac5e34455680d.tar.gz
rust-727f01700b074181bddf49caa07ac5e34455680d.zip
write code to extract region names and emit new style message
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/borrow_check/mod.rs10
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs61
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs256
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/mod.rs5
-rw-r--r--src/librustc_mir/borrow_check/nll/universal_regions.rs32
-rw-r--r--src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs2
-rw-r--r--src/test/compile-fail/mir_check_cast_closure.rs2
-rw-r--r--src/test/compile-fail/mir_check_cast_reify.rs2
-rw-r--r--src/test/compile-fail/mir_check_cast_unsafe_fn.rs2
-rw-r--r--src/test/compile-fail/mir_check_cast_unsize.rs3
-rw-r--r--src/test/compile-fail/regions-static-bound.rs2
-rw-r--r--src/test/ui/borrowck/issue-45983.nll.stderr10
-rw-r--r--src/test/ui/borrowck/issue-7573.nll.stderr10
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr10
-rw-r--r--src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr10
-rw-r--r--src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr10
-rw-r--r--src/test/ui/closure-expected-type/expect-region-supply-region.nll.stderr32
-rw-r--r--src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr8
-rw-r--r--src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr10
-rw-r--r--src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.stderr7
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs3
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr16
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr13
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr10
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr11
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr13
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr9
-rw-r--r--src/test/ui/nll/issue-48238.rs2
-rw-r--r--src/test/ui/nll/issue-48238.stderr12
-rw-r--r--src/test/ui/nll/issue-50716.rs2
-rw-r--r--src/test/ui/nll/issue-50716.stderr6
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.rs6
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr18
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs6
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr18
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr6
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr7
49 files changed, 523 insertions, 155 deletions
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 3aaa3378bb0..3417021640f 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -128,6 +128,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
     input_mir: &Mir<'gcx>,
     def_id: DefId,
 ) -> BorrowCheckResult<'gcx> {
+    debug!("do_mir_borrowck(def_id = {:?})", def_id);
+
     let tcx = infcx.tcx;
     let attributes = tcx.get_attrs(def_id);
     let param_env = tcx.param_env(def_id);
@@ -319,10 +321,14 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         }
     }
 
-    BorrowCheckResult {
+    let result = BorrowCheckResult {
         closure_requirements: opt_closure_req,
         used_mut_upvars: mbcx.used_mut_upvars,
-    }
+    };
+
+    debug!("do_mir_borrowck: result = {:#?}", result);
+
+    result
 }
 
 #[allow(dead_code)]
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 5a86f2432d8..786b6a77d2b 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
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use borrow_check::nll::region_infer::values::ToElementIndex;
-use borrow_check::nll::region_infer::{Cause, ConstraintIndex, RegionInferenceContext};
 use borrow_check::nll::region_infer::{ConstraintIndex, RegionInferenceContext};
 use borrow_check::nll::type_check::Locations;
 use rustc::hir::def_id::DefId;
@@ -22,6 +21,8 @@ use rustc_data_structures::indexed_vec::IndexVec;
 use std::fmt;
 use syntax_pos::Span;
 
+mod region_name;
+
 /// Constraints that are considered interesting can be categorized to
 /// determine why they are interesting. Order of variants indicates
 /// sort order of the category, thereby influencing diagnostic output.
@@ -200,10 +201,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ) {
         debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
 
-        let fr_name = self.to_error_region(fr);
-        let outlived_fr_name = self.to_error_region(outlived_fr);
-
-        if let (Some(f), Some(o)) = (fr_name, outlived_fr_name) {
+        if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
             let tables = infcx.tcx.typeck_tables_of(mir_def_id);
             let nice = NiceRegionError::new_from_span(infcx.tcx, blame_span, o, f, Some(tables));
             if let Some(_error_reported) = nice.try_report() {
@@ -211,16 +209,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             }
         }
 
-        let fr_string = match fr_name {
-            Some(r) => format!("free region `{}`", r),
-            None => format!("free region `{:?}`", fr),
-        };
-
-        let outlived_fr_string = match outlived_fr_name {
-            Some(r) => format!("free region `{}`", r),
-            None => format!("free region `{:?}`", outlived_fr),
-        };
-
         // Find all paths
         let constraint_paths = self.find_constraint_paths_between_regions(outlived_fr, |r| r == fr);
         debug!("report_error: constraint_paths={:#?}", constraint_paths);
@@ -239,25 +227,34 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0));
         debug!("report_error: sorted_path={:?}", categorized_path);
 
-        // If we found something, cite that as the main cause of the problem.
-        if let Some((category, span)) = categorized_path.first() {
-            let mut diag = infcx.tcx.sess.struct_span_err(
-                *span,
-                &format!(
-                    "{} requires that data must outlive {}",
-                    category, outlived_fr_string
-                ),
-            );
+        // Get a span
+        let (category, span) = categorized_path.first().unwrap();
+        let diag = &mut infcx.tcx.sess.struct_span_err(
+            *span,
+            &format!("unsatisfied lifetime constraints"), // FIXME
+        );
 
-            diag.emit();
-        } else {
-            let mut diag = infcx.tcx.sess.struct_span_err(
-                blame_span,
-                &format!("{} does not outlive {}", fr_string, outlived_fr_string,),
-            );
+        // Figure out how we can refer
+        let counter = &mut 1;
+        let fr_name = self.give_region_a_name(infcx.tcx, mir, mir_def_id, fr, counter, diag);
+        let outlived_fr_name = self.give_region_a_name(
+            infcx.tcx,
+            mir,
+            mir_def_id,
+            outlived_fr,
+            counter,
+            diag,
+        );
 
-            diag.emit();
-        }
+        diag.span_label(
+            *span,
+            format!(
+                "{} requires that `{}` must outlive `{}`",
+                category, fr_name, outlived_fr_name,
+            ),
+        );
+
+        diag.emit();
     }
 
     // Find some constraint `X: Y` where:
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
new file mode 100644
index 00000000000..bf8c9c8c3be
--- /dev/null
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -0,0 +1,256 @@
+// 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.
+
+use borrow_check::nll::region_infer::RegionInferenceContext;
+use borrow_check::nll::ToRegionVid;
+use rustc::hir::def_id::DefId;
+use rustc::mir::{Local, Mir};
+use rustc::ty::{self, RegionVid, TyCtxt};
+use rustc_data_structures::indexed_vec::Idx;
+use rustc_errors::DiagnosticBuilder;
+use syntax::ast::Name;
+use syntax::symbol::keywords;
+use syntax_pos::symbol::InternedString;
+
+impl<'tcx> RegionInferenceContext<'tcx> {
+    /// Maps from an internal MIR region vid to something that we can
+    /// report to the user. In some cases, the region vids will map
+    /// directly to lifetimes that the user has a name for (e.g.,
+    /// `'static`). But frequently they will not, in which case we
+    /// have to find some way to identify the lifetime to the user. To
+    /// that end, this function takes a "diagnostic" so that it can
+    /// create auxiliary notes as needed.
+    ///
+    /// Example (function arguments):
+    ///
+    /// Suppose we are trying to give a name to the lifetime of the
+    /// reference `x`:
+    ///
+    /// ```
+    /// fn foo(x: &u32) { .. }
+    /// ```
+    ///
+    /// This function would create a label like this:
+    ///
+    /// ```
+    ///  | fn foo(x: &u32) { .. }
+    ///           ------- fully elaborated type of `x` is `&'1 u32`
+    /// ```
+    ///
+    /// and then return the name `'1` for us to use.
+    crate fn give_region_a_name(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        mir_def_id: DefId,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder,
+    ) -> InternedString {
+        debug!("give_region_a_name(fr={:?}, counter={})", fr, counter);
+
+        assert!(self.universal_regions.is_universal_region(fr));
+
+        self.give_name_from_error_region(tcx, mir_def_id, fr, counter, diag)
+            .or_else(|| {
+                self.give_name_if_anonymous_region_appears_in_arguments(tcx, mir, fr, counter, diag)
+            })
+            .or_else(|| {
+                self.give_name_if_anonymous_region_appears_in_upvars(tcx, mir, fr, counter, diag)
+            })
+            .or_else(|| {
+                self.give_name_if_anonymous_region_appears_in_output(tcx, mir, fr, counter, diag)
+            })
+            .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr))
+    }
+
+    /// Check for the case where `fr` maps to something that the
+    /// *user* has a name for. In that case, we'll be able to map
+    /// `fr` to a `Region<'tcx>`, and that region will be one of
+    /// named variants.
+    fn give_name_from_error_region(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir_def_id: DefId,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let error_region = self.to_error_region(fr)?;
+        debug!("give_region_a_name: error_region = {:?}", error_region);
+        match error_region {
+            ty::ReEarlyBound(ebr) => Some(ebr.name),
+
+            ty::ReStatic => Some(keywords::StaticLifetime.name().as_interned_str()),
+
+            ty::ReFree(free_region) => match free_region.bound_region {
+                ty::BoundRegion::BrNamed(_, name) => Some(name),
+
+                ty::BoundRegion::BrEnv => {
+                    let closure_span = tcx.hir.span_if_local(mir_def_id).unwrap();
+                    let region_name = self.synthesize_region_name(counter);
+                    diag.span_label(
+                        closure_span,
+                        format!("lifetime `{}` represents the closure body", region_name),
+                    );
+                    Some(region_name)
+                }
+
+                ty::BoundRegion::BrAnon(_) | ty::BoundRegion::BrFresh(_) => None,
+            },
+
+            ty::ReLateBound(..)
+            | ty::ReScope(..)
+            | ty::ReVar(..)
+            | ty::ReSkolemized(..)
+            | ty::ReEmpty
+            | ty::ReErased
+            | ty::ReClosureBound(..)
+            | ty::ReCanonical(..) => None,
+        }
+    }
+
+    /// Find an argument that contains `fr` and label it with a fully
+    /// elaborated type, returning something like `'1`. Result looks
+    /// like:
+    ///
+    /// ```
+    ///  | fn foo(x: &u32) { .. }
+    ///           ------- fully elaborated type of `x` is `&'1 u32`
+    /// ```
+    fn give_name_if_anonymous_region_appears_in_arguments(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
+        let argument_index = self.universal_regions
+            .unnormalized_input_tys
+            .iter()
+            .skip(implicit_inputs)
+            .position(|arg_ty| {
+                debug!("give_name_if_anonymous_region_appears_in_arguments: arg_ty = {:?}", arg_ty);
+                tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
+            })?
+            + implicit_inputs;
+
+        debug!(
+            "give_name_if_anonymous_region_appears_in_arguments: \
+             found {:?} in argument {} which has type {:?}",
+            fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index],
+        );
+
+        let region_name = self.synthesize_region_name(counter);
+
+        let argument_local = Local::new(argument_index + 1);
+        let argument_span = mir.local_decls[argument_local].source_info.span;
+        diag.span_label(
+            argument_span,
+            format!("lifetime `{}` appears in this argument", region_name,),
+        );
+
+        Some(region_name)
+    }
+
+    /// Find a closure upvar that contains `fr` and label it with a
+    /// fully elaborated type, returning something like `'1`. Result
+    /// looks like:
+    ///
+    /// ```
+    ///  | let x = Some(&22);
+    ///        - fully elaborated type of `x` is `Option<&'1 u32>`
+    /// ```
+    fn give_name_if_anonymous_region_appears_in_upvars(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let upvar_index = self.universal_regions
+            .defining_ty
+            .upvar_tys(tcx)
+            .position(|upvar_ty| {
+                debug!(
+                    "give_name_if_anonymous_region_appears_in_upvars: upvar_ty = {:?}",
+                    upvar_ty,
+                );
+                tcx.any_free_region_meets(&upvar_ty, |r| r.to_region_vid() == fr)
+            })?;
+
+        debug!(
+            "give_name_if_anonymous_region_appears_in_upvars: \
+             found {:?} in upvar {} which has type {:?}",
+            fr,
+            upvar_index,
+            self.universal_regions
+                .defining_ty
+                .upvar_tys(tcx)
+                .nth(upvar_index),
+        );
+
+        let region_name = self.synthesize_region_name(counter);
+
+        let upvar_hir_id = mir.upvar_decls[upvar_index].var_hir_id.assert_crate_local();
+        let upvar_node_id = tcx.hir.hir_to_node_id(upvar_hir_id);
+        let upvar_span = tcx.hir.span(upvar_node_id);
+        let upvar_name = tcx.hir.name(upvar_node_id);
+        diag.span_label(
+            upvar_span,
+            format!(
+                "lifetime `{}` appears in the type of `{}`",
+                region_name, upvar_name,
+            ),
+        );
+
+        Some(region_name)
+    }
+
+    /// Check for arguments appearing in the (closure) return type. It
+    /// must be a closure since, in a free fn, such an argument would
+    /// have to either also appear in an argument (if using elision)
+    /// or be early bound (named, not in argument).
+    fn give_name_if_anonymous_region_appears_in_output(
+        &self,
+        tcx: TyCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        fr: RegionVid,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let return_ty = self.universal_regions
+            .unnormalized_output_ty;
+        debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty);
+        if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) {
+            return None;
+        }
+
+        let region_name = self.synthesize_region_name(counter);
+        diag.span_label(
+            mir.span,
+            format!("lifetime `{}` appears in return type", region_name),
+        );
+
+        Some(region_name)
+    }
+
+    /// Create a synthetic region named `'1`, incrementing the
+    /// counter.
+    fn synthesize_region_name(&self, counter: &mut usize) -> InternedString {
+        let c = *counter;
+        *counter += 1;
+
+        Name::intern(&format!("'{:?}", c)).as_interned_str()
+    }
+}
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 13cc0c0419e..164941203e0 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -256,6 +256,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     fn init_universal_regions(&mut self) {
         // Update the names (if any)
         for (external_name, variable) in self.universal_regions.named_universal_regions() {
+            debug!(
+                "init_universal_regions: region {:?} has external name {:?}",
+                variable,
+                external_name
+            );
             self.definitions[variable].external_name = Some(external_name);
         }
 
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index acd740e5412..8590e3d0765 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -22,6 +22,7 @@
 //! The code in this file doesn't *do anything* with those results; it
 //! just returns them for other code to use.
 
+use either::Either;
 use rustc::hir::def_id::DefId;
 use rustc::hir::{self, BodyOwnerKind, HirId};
 use rustc::infer::outlives::bounds::{self, OutlivesBound};
@@ -128,6 +129,34 @@ pub enum DefiningTy<'tcx> {
     Const(DefId, &'tcx Substs<'tcx>),
 }
 
+impl<'tcx> DefiningTy<'tcx> {
+    /// Returns a list of all the upvar types for this MIR. If this is
+    /// not a closure or generator, there are no upvars, and hence it
+    /// will be an empty list. The order of types in this list will
+    /// match up with the `upvar_decls` field of `Mir`.
+    pub fn upvar_tys(self, tcx: TyCtxt<'_, '_, 'tcx>) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
+        match self {
+            DefiningTy::Closure(def_id, substs) => Either::Left(substs.upvar_tys(def_id, tcx)),
+            DefiningTy::Generator(def_id, substs, _) => {
+                Either::Right(Either::Left(substs.upvar_tys(def_id, tcx)))
+            }
+            DefiningTy::FnDef(..) | DefiningTy::Const(..) => {
+                Either::Right(Either::Right(iter::empty()))
+            }
+        }
+    }
+
+    /// Number of implicit inputs -- notably the "environment"
+    /// parameter for closures -- that appear in MIR but not in the
+    /// user's code.
+    pub fn implicit_inputs(self) -> usize {
+        match self {
+            DefiningTy::Closure(..) | DefiningTy::Generator(..) => 1,
+            DefiningTy::FnDef(..) | DefiningTy::Const(..) => 0,
+        }
+    }
+}
+
 #[derive(Debug)]
 struct UniversalRegionIndices<'tcx> {
     /// For those regions that may appear in the parameter environment
@@ -542,6 +571,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
                     tables.node_id_to_type(self.mir_hir_id)
                 };
 
+                debug!("defining_ty (pre-replacement): {:?}", defining_ty);
+
                 let defining_ty = self.infcx
                     .replace_free_regions_with_nll_infer_vars(FR, &defining_ty);
 
@@ -802,6 +833,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
     /// insert the `ReFree` version of those into the map as
     /// well. These are used for error reporting.
     fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, vid: ty::RegionVid) {
+        debug!("insert_late_bound_region({:?}, {:?})", r, vid);
         self.indices.insert(r, vid);
     }
 
diff --git a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
index 3a7e4a13740..b821c7cfa34 100644
--- a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
+++ b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs
@@ -302,7 +302,7 @@ fn main() {
         // FIXME(#49824) -- the free region error below should probably not be there
         let mut x = 0;
            || {
-               || { //[mir]~ ERROR free region `` does not outlive
+               || { //[mir]~ ERROR unsatisfied lifetime constraints
                    let y = &mut x;
                    &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
                    //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
diff --git a/src/test/compile-fail/mir_check_cast_closure.rs b/src/test/compile-fail/mir_check_cast_closure.rs
index d8f5956b585..2200c1569e5 100644
--- a/src/test/compile-fail/mir_check_cast_closure.rs
+++ b/src/test/compile-fail/mir_check_cast_closure.rs
@@ -14,7 +14,7 @@
 
 fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 {
     let g: fn(_, _) -> _ = |_x, y| y;
-    //~^ ERROR free region `'b` does not outlive free region `'a`
+    //~^ ERROR unsatisfied lifetime constraints
     g
     //~^ WARNING not reporting region error due to nll
 }
diff --git a/src/test/compile-fail/mir_check_cast_reify.rs b/src/test/compile-fail/mir_check_cast_reify.rs
index 1f9174b3574..f85104dff86 100644
--- a/src/test/compile-fail/mir_check_cast_reify.rs
+++ b/src/test/compile-fail/mir_check_cast_reify.rs
@@ -45,7 +45,7 @@ fn bar<'a>(x: &'a u32) -> &'static u32 {
     // as part of checking the `ReifyFnPointer`.
     let f: fn(_) -> _ = foo;
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR free region `'a` does not outlive free region `'static`
+    //~| ERROR unsatisfied lifetime constraints
     f(x)
 }
 
diff --git a/src/test/compile-fail/mir_check_cast_unsafe_fn.rs b/src/test/compile-fail/mir_check_cast_unsafe_fn.rs
index 27ca2728ddf..e90242f3f87 100644
--- a/src/test/compile-fail/mir_check_cast_unsafe_fn.rs
+++ b/src/test/compile-fail/mir_check_cast_unsafe_fn.rs
@@ -17,7 +17,7 @@ fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
     // in `g`. These are related via the `UnsafeFnPointer` cast.
     let g: unsafe fn(_) -> _ = f;
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR free region `'a` does not outlive free region `'static`
+    //~| ERROR unsatisfied lifetime constraints
     unsafe { g(input) }
 }
 
diff --git a/src/test/compile-fail/mir_check_cast_unsize.rs b/src/test/compile-fail/mir_check_cast_unsize.rs
index a2c840a7098..d242186a6f7 100644
--- a/src/test/compile-fail/mir_check_cast_unsize.rs
+++ b/src/test/compile-fail/mir_check_cast_unsize.rs
@@ -15,8 +15,7 @@
 use std::fmt::Debug;
 
 fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
-    //~^ ERROR free region `'a` does not outlive free region `'static`
-    x
+    x //~ ERROR unsatisfied lifetime constraints
     //~^ WARNING not reporting region error due to nll
 }
 
diff --git a/src/test/compile-fail/regions-static-bound.rs b/src/test/compile-fail/regions-static-bound.rs
index a0097b9f6d7..0a37df4f0c7 100644
--- a/src/test/compile-fail/regions-static-bound.rs
+++ b/src/test/compile-fail/regions-static-bound.rs
@@ -18,7 +18,7 @@ fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
 fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
     t //[ll]~ ERROR E0312
         //[nll]~^ WARNING not reporting region error due to nll
-        //[nll]~| ERROR free region `'a` does not outlive free region `'static`
+        //[nll]~| ERROR unsatisfied lifetime constraints
 }
 
 fn error(u: &(), v: &()) {
diff --git a/src/test/ui/borrowck/issue-45983.nll.stderr b/src/test/ui/borrowck/issue-45983.nll.stderr
index a008a408d97..68a039262c1 100644
--- a/src/test/ui/borrowck/issue-45983.nll.stderr
+++ b/src/test/ui/borrowck/issue-45983.nll.stderr
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     give_any(|y| x = Some(y));
    |                           ^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/issue-45983.rs:17:27
+error: unsatisfied lifetime constraints
+  --> $DIR/issue-45983.rs:17:18
    |
+LL |     let x = None;
+   |         - lifetime `'2` appears in the type of `x`
 LL |     give_any(|y| x = Some(y));
-   |                           ^
+   |               -  ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
+   |               |
+   |               lifetime `'1` appears in this argument
 
 error[E0594]: cannot assign to immutable item `x`
   --> $DIR/issue-45983.rs:17:18
diff --git a/src/test/ui/borrowck/issue-7573.nll.stderr b/src/test/ui/borrowck/issue-7573.nll.stderr
index 84c6236eb0a..daa0a320b88 100644
--- a/src/test/ui/borrowck/issue-7573.nll.stderr
+++ b/src/test/ui/borrowck/issue-7573.nll.stderr
@@ -4,11 +4,17 @@ warning: not reporting region error due to nll
 LL |     let mut lines_to_use: Vec<&CrateId> = Vec::new();
    |                               ^
 
-error: free region `` does not outlive free region `'_#2r`
+error: unsatisfied lifetime constraints
   --> $DIR/issue-7573.rs:32:9
    |
+LL |     let mut lines_to_use: Vec<&CrateId> = Vec::new();
+   |         ---------------- lifetime `'2` appears in the type of `lines_to_use`
+LL |         //~^ NOTE cannot infer an appropriate lifetime
+LL |     let push_id = |installed_id: &CrateId| {
+   |                    ------------ lifetime `'1` appears in this argument
+...
 LL |         lines_to_use.push(installed_id);
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr
index ee3970aa8fd..4f7843b7248 100644
--- a/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr
+++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.nll.stderr
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     with_int(|y| x = Some(y));
    |                           ^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/regions-escape-bound-fn-2.rs:18:27
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-escape-bound-fn-2.rs:18:18
    |
+LL |     let mut x = None;
+   |         ----- lifetime `'2` appears in the type of `x`
 LL |     with_int(|y| x = Some(y));
-   |                           ^
+   |               -  ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
+   |               |
+   |               lifetime `'1` appears in this argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr
index 07a4ab1dbb1..9b107ae08b4 100644
--- a/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr
+++ b/src/test/ui/borrowck/regions-escape-bound-fn.nll.stderr
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     with_int(|y| x = Some(y));
    |                      ^^^^^^^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/regions-escape-bound-fn.rs:18:27
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-escape-bound-fn.rs:18:18
    |
+LL |     let mut x: Option<&isize> = None;
+   |         ----- lifetime `'2` appears in the type of `x`
 LL |     with_int(|y| x = Some(y));
-   |                           ^
+   |               -  ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
+   |               |
+   |               lifetime `'1` appears in this argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr
index 14c255ef527..8095330154d 100644
--- a/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr
+++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.nll.stderr
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     with_int(&mut |y| x = Some(y));
    |                           ^^^^^^^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/regions-escape-unboxed-closure.rs:16:32
+error: unsatisfied lifetime constraints
+  --> $DIR/regions-escape-unboxed-closure.rs:16:23
    |
+LL |     let mut x: Option<&isize> = None;
+   |         ----- lifetime `'2` appears in the type of `x`
 LL |     with_int(&mut |y| x = Some(y));
-   |                                ^
+   |                    -  ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
+   |                    |
+   |                    lifetime `'1` appears in this argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closure-expected-type/expect-region-supply-region.nll.stderr b/src/test/ui/closure-expected-type/expect-region-supply-region.nll.stderr
index bbae80e16ab..5487d34813b 100644
--- a/src/test/ui/closure-expected-type/expect-region-supply-region.nll.stderr
+++ b/src/test/ui/closure-expected-type/expect-region-supply-region.nll.stderr
@@ -22,23 +22,37 @@ warning: not reporting region error due to nll
 LL |         f = Some(x);
    |             ^^^^^^^
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/expect-region-supply-region.rs:28:18
+error: unsatisfied lifetime constraints
+  --> $DIR/expect-region-supply-region.rs:28:9
    |
+LL |     let mut f: Option<&u32> = None;
+   |         ----- lifetime `'2` appears in the type of `f`
+LL |     closure_expecting_bound(|x| {
+   |                              - lifetime `'1` appears in this argument
 LL |         f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
-   |                  ^
+   |         ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/expect-region-supply-region.rs:38:18
+error: unsatisfied lifetime constraints
+  --> $DIR/expect-region-supply-region.rs:38:9
    |
+LL |     let mut f: Option<&u32> = None;
+   |         ----- lifetime `'2` appears in the type of `f`
+LL |     closure_expecting_bound(|x: &u32| {
+   |                              - lifetime `'1` appears in this argument
 LL |         f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
-   |                  ^
+   |         ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
 
-error: free region `` does not outlive free region `'_#2r`
-  --> $DIR/expect-region-supply-region.rs:52:18
+error: unsatisfied lifetime constraints
+  --> $DIR/expect-region-supply-region.rs:52:9
    |
+LL |     let mut f: Option<&u32> = None;
+   |         ----- lifetime `'2` appears in the type of `f`
+...
+LL |     closure_expecting_bound(|x: &'x u32| {
+   |                              - lifetime `'1` appears in this argument
+...
 LL |         f = Some(x);
-   |                  ^
+   |         ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr
index 5ae6afa7b17..9c7e3db67a6 100644
--- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr
+++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr
@@ -4,11 +4,15 @@ warning: not reporting region error due to nll
 LL |     invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495
    |     ^^^^^^
 
-error: free region `` does not outlive free region `'_#2r`
+error: unsatisfied lifetime constraints
   --> $DIR/E0621-does-not-trigger-for-closures.rs:25:26
    |
 LL |     invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495
-   |                          ^^^^^
+   |                ----------^^^^^-----------------
+   |                |   |     |
+   |                |   |     free region requires that `'1` must outlive `'2`
+   |                |   lifetime `'1` appears in this argument
+   |                lifetime `'2` appears in return type
 
 error: aborting due to previous error
 
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 7099316d694..9aad7efdee5 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
@@ -10,17 +10,19 @@ warning: not reporting region error due to nll
 LL |         self.x.iter().map(|a| a.0)
    |                ^^^^
 
-error: free region `` does not outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/static-return-lifetime-infered.rs:17:9
    |
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+   |                         ----- lifetime `'1` appears in this argument
 LL |         self.x.iter().map(|a| a.0)
-   |         ^^^^^^^^^^^^^
+   |         ^^^^^^ cast requires that `'1` must outlive `'static`
 
-error: free region `'a` does not outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/static-return-lifetime-infered.rs:21:9
    |
 LL |         self.x.iter().map(|a| a.0)
-   |         ^^^^^^^^^^^^^
+   |         ^^^^^^ cast requires that `'a` must outlive `'static`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr
index 4cf7feddd46..19e10ba6da8 100644
--- a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr
+++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr
@@ -4,11 +4,11 @@ warning: not reporting region error due to nll
 LL |     static_val(x); //~ ERROR cannot infer
    |                ^
 
-error: free region `'a` does not outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/dyn-trait.rs:32:5
    |
 LL |     static_val(x); //~ ERROR cannot infer
-   |     ^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^ argument requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.rs b/src/test/ui/nll/closure-requirements/escape-argument-callee.rs
index 1e168028c7c..78208d6d7db 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.rs
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.rs
@@ -34,7 +34,7 @@ fn test() {
     {
         let y = 22;
         let mut closure = expect_sig(|p, y| *p = y);
-        //~^ ERROR does not outlive free region
+        //~^ ERROR
         //~| WARNING not reporting region error due to nll
         closure(&mut p, &y);
     }
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index 067b5ebc6c4..d6f54218360 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -4,11 +4,14 @@ warning: not reporting region error due to nll
 LL |         let mut closure = expect_sig(|p, y| *p = y);
    |                                                  ^
 
-error: free region `ReFree(DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]), BrAnon(3))` does not outlive free region `ReFree(DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]), BrAnon(2))`
+error: unsatisfied lifetime constraints
   --> $DIR/escape-argument-callee.rs:36:45
    |
 LL |         let mut closure = expect_sig(|p, y| *p = y);
-   |                                             ^^^^^^
+   |                                       -  -  ^^^^^^ free region requires that `'1` must outlive `'2`
+   |                                       |  |
+   |                                       |  lifetime `'1` appears in this argument
+   |                                       lifetime `'2` appears in this argument
 
 note: No external requirements
   --> $DIR/escape-argument-callee.rs:36:38
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
index e7ec0b9684d..b879f9a3398 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs
@@ -54,8 +54,7 @@ fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell
             // Only works if 'x: 'y:
             let p = x.get();
             //~^ WARN not reporting region error due to nll
-            //~| ERROR does not outlive free region
-            demand_y(x, y, p)
+            demand_y(x, y, p) //~ ERROR
         },
     );
 }
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 c88f0efba6f..a7a50a3a029 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
@@ -4,11 +4,16 @@ warning: not reporting region error due to nll
 LL |             let p = x.get();
    |                     ^^^^^^^
 
-error: free region `ReFree(DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]), BrAnon(1))` does not outlive free region `ReFree(DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]), BrAnon(2))`
-  --> $DIR/propagate-approximated-fail-no-postdom.rs:55:17
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-approximated-fail-no-postdom.rs:57:13
    |
-LL |             let p = x.get();
-   |                 ^
+LL |         |_outlives1, _outlives2, _outlives3, x, y| {
+   |          ----------              ---------- lifetime `'2` appears in this argument
+   |          |
+   |          lifetime `'1` appears in this argument
+...
+LL |             demand_y(x, y, p) //~ ERROR
+   |             ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 note: No external requirements
   --> $DIR/propagate-approximated-fail-no-postdom.rs:53:9
@@ -17,8 +22,7 @@ LL | /         |_outlives1, _outlives2, _outlives3, x, y| {
 LL | |             // Only works if 'x: 'y:
 LL | |             let p = x.get();
 LL | |             //~^ WARN not reporting region error due to nll
-LL | |             //~| ERROR does not outlive free region
-LL | |             demand_y(x, y, p)
+LL | |             demand_y(x, y, p) //~ ERROR
 LL | |         },
    | |_________^
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs
index 5a71e75d4b2..a8ab41cebac 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs
@@ -31,7 +31,7 @@ fn case1() {
     foo(cell, |cell_a, cell_x| {
         //~^ WARNING not reporting region error due to nll
         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
-        //~^ ERROR argument requires that data must outlive free region
+        //~^ ERROR
     })
 }
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index 656c1b46a3c..96f3d6a6a53 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -4,11 +4,16 @@ warning: not reporting region error due to nll
 LL |     foo(cell, |cell_a, cell_x| {
    |     ^^^
 
-error: argument requires that data must outlive free region `'_#1r`
-  --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:20
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:33:9
    |
+LL |     foo(cell, |cell_a, cell_x| {
+   |                ------  ------ lifetime `'1` appears in this argument
+   |                |
+   |                lifetime `'2` appears in this argument
+LL |         //~^ WARNING not reporting region error due to nll
 LL |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
-   |                    ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:31:15
@@ -17,7 +22,7 @@ LL |       foo(cell, |cell_a, cell_x| {
    |  _______________^
 LL | |         //~^ WARNING not reporting region error due to nll
 LL | |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |     })
    | |_____^
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs
index b25b0e25df2..26faccdde71 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,7 @@ 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 argument requires that data must outlive free region
+        //~^ ERROR
 
         // Only works if 'x: 'y:
         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index 40f215619c6..f65e7161ca8 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
@@ -9,7 +9,7 @@ note: External requirements
    |
 LL |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
    |  _______________________________________________^
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
@@ -23,23 +23,23 @@ LL | |     });
    = note: number of external vids: 2
    = note: where '_#1r: '_#0r
 
-error: argument requires that data must outlive free region `ReStatic`
+error: unsatisfied lifetime constraints
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5
    |
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
 LL | |     });
-   | |______^
+   | |______^ argument requires that `'a` must outlive `'static`
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1
    |
 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 argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |
 ...  |
 LL | |     });
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs
index db9951bcc0f..703d60371cd 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,7 @@ 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 argument requires that data must outlive free region
+        //~^ ERROR
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
         //~^ WARNING not reporting region error due to nll
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index d89ff028a50..f1b2c9f198d 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
@@ -9,7 +9,7 @@ note: External requirements
    |
 LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
    |  _______________________________________________^
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARNING not reporting region error due to nll
@@ -23,23 +23,23 @@ LL | |     });
    = note: number of external vids: 3
    = note: where '_#1r: '_#0r
 
-error: argument requires that data must outlive free region `ReStatic`
+error: unsatisfied lifetime constraints
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5
    |
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-LL | |         //~^ ERROR argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     });
-   | |______^
+   | |______^ argument requires that `'a` must outlive `'static`
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1
    |
 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 argument requires that data must outlive free region
+LL | |         //~^ ERROR
 LL | |         // Only works if 'x: 'y:
 ...  |
 LL | |     });
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs
index 316268e7e72..4b1f5231b3e 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs
@@ -46,7 +46,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
         //~^ WARN not reporting region error due to nll
-        //~| ERROR argument requires that data must outlive free region
+        //~| ERROR
     });
 }
 
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 74c0576e03b..fb98c506c7d 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
@@ -4,11 +4,16 @@ warning: not reporting region error due to nll
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: argument requires that data must outlive free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(2))`
+error: unsatisfied lifetime constraints
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
    |
+LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
+   |                                                ---------  - lifetime `'1` appears in this argument
+   |                                                |
+   |                                                lifetime `'2` appears in this argument
+LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
-   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:45:47
@@ -18,7 +23,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARN not reporting region error due to nll
-LL | |         //~| ERROR argument requires that data must outlive free region
+LL | |         //~| ERROR
 LL | |     });
    | |_____^
    |
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs
index afb61b221be..62a20c1bfe7 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs
@@ -50,7 +50,7 @@ fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
         // Only works if 'x: 'y:
         demand_y(x, y, x.get())
         //~^ WARN not reporting region error due to nll
-        //~| ERROR does not outlive free region
+        //~| ERROR
     });
 }
 
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 2fd6ce50095..73d39a8502b 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
@@ -4,11 +4,16 @@ warning: not reporting region error due to nll
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(2))` does not outlive free region `ReFree(DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]), BrAnon(4))`
-  --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:18
+error: unsatisfied lifetime constraints
+  --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
    |
+LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
+   |                                                ----------  ---------- lifetime `'2` appears in this argument
+   |                                                |
+   |                                                lifetime `'1` appears in this argument
+LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
-   |                  ^
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
 
 note: No external requirements
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:49:47
@@ -18,7 +23,7 @@ LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x,
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARN not reporting region error due to nll
-LL | |         //~| ERROR does not outlive free region
+LL | |         //~| ERROR
 LL | |     });
    | |_____^
    |
diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs
index dedbd8df41b..b5e8c95bc13 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs
+++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs
@@ -18,7 +18,7 @@
 fn foo<'a>(x: &'a u32) -> &'static u32 {
     &*x
         //~^ WARN not reporting region error due to nll
-        //~| ERROR does not outlive free region
+        //~| ERROR
 }
 
 fn main() { }
diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
index 9520b446303..d012dca2527 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
+++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
@@ -4,11 +4,11 @@ warning: not reporting region error due to nll
 LL |     &*x
    |     ^^^
 
-error: free region `ReFree(DefId(0/0:3 ~ region_lbr_named_does_not_outlive_static[317d]::foo[0]), BrNamed(crate0:DefIndex(1:9), 'a))` does not outlive free region `ReStatic`
+error: unsatisfied lifetime constraints
   --> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5
    |
 LL |     &*x
-   |     ^^^
+   |     ^^^ free region requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs
index 60f82ca0eef..d88729d04d9 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.rs
@@ -20,7 +20,7 @@
 fn test() {
     expect_sig(|a, b| b); // ought to return `a`
     //~^ WARN not reporting region error due to nll
-    //~| ERROR does not outlive free region
+    //~| ERROR
 }
 
 fn expect_sig<F>(f: F) -> F
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 04ff4aaadf8..5724cdbd8c9 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -4,11 +4,14 @@ warning: not reporting region error due to nll
 LL |     expect_sig(|a, b| b); // ought to return `a`
    |                       ^
 
-error: free region `ReFree(DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]), BrAnon(2))` does not outlive free region `ReFree(DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]), BrAnon(1))`
+error: unsatisfied lifetime constraints
   --> $DIR/return-wrong-bound-region.rs:21:23
    |
 LL |     expect_sig(|a, b| b); // ought to return `a`
-   |                       ^
+   |                 -  -  ^ free region requires that `'1` must outlive `'2`
+   |                 |  |
+   |                 |  lifetime `'1` appears in this argument
+   |                 lifetime `'2` appears in this argument
 
 note: No external requirements
   --> $DIR/return-wrong-bound-region.rs:21:16
@@ -27,7 +30,7 @@ note: No external requirements
 LL | / fn test() {
 LL | |     expect_sig(|a, b| b); // ought to return `a`
 LL | |     //~^ WARN not reporting region error due to nll
-LL | |     //~| ERROR does not outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
diff --git a/src/test/ui/nll/issue-48238.rs b/src/test/ui/nll/issue-48238.rs
index 6f7644da3d3..7c5527ae1e7 100644
--- a/src/test/ui/nll/issue-48238.rs
+++ b/src/test/ui/nll/issue-48238.rs
@@ -18,5 +18,5 @@ fn use_val<'a>(val: &'a u8) -> &'a u8 {
 
 fn main() {
     let orig: u8 = 5;
-    move || use_val(&orig); //~ ERROR free region `` does not outlive free region `'_#1r`
+    move || use_val(&orig); //~ ERROR
 }
diff --git a/src/test/ui/nll/issue-48238.stderr b/src/test/ui/nll/issue-48238.stderr
index 29385d9b243..7bdac345e90 100644
--- a/src/test/ui/nll/issue-48238.stderr
+++ b/src/test/ui/nll/issue-48238.stderr
@@ -1,8 +1,12 @@
-error: free region `` does not outlive free region `'_#1r`
-  --> $DIR/issue-48238.rs:21:21
+error: unsatisfied lifetime constraints
+  --> $DIR/issue-48238.rs:21:13
    |
-LL |     move || use_val(&orig); //~ ERROR free region `` does not outlive free region `'_#1r`
-   |                     ^^^^^
+LL |     move || use_val(&orig); //~ ERROR
+   |     --------^^^^^^^^^^^^^^
+   |     |       |
+   |     |       argument requires that `'1` must outlive `'2`
+   |     lifetime `'1` represents the closure body
+   |     lifetime `'2` appears in return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/issue-50716.rs b/src/test/ui/nll/issue-50716.rs
index a41af168c3e..beb2ff79e90 100644
--- a/src/test/ui/nll/issue-50716.rs
+++ b/src/test/ui/nll/issue-50716.rs
@@ -22,7 +22,7 @@ where
     for<'b> &'b T: A,
     <&'static T as A>::X: Sized
 {
-    let _x = *s; //~ ERROR assignment requires that data must outlive free region `'static`
+    let _x = *s; //~ ERROR
 }
 
 fn main() {}
diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr
index de69f8cfbcb..48862166f89 100644
--- a/src/test/ui/nll/issue-50716.stderr
+++ b/src/test/ui/nll/issue-50716.stderr
@@ -1,8 +1,8 @@
-error: assignment requires that data must outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/issue-50716.rs:25:14
    |
-LL |     let _x = *s; //~ ERROR assignment requires that data must outlive free region `'static`
-   |              ^^
+LL |     let _x = *s; //~ ERROR
+   |              ^^ assignment requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs
index 3832be6288a..0a8801a3c4d 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.rs
@@ -55,7 +55,7 @@ where
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
@@ -67,7 +67,7 @@ where
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
@@ -89,7 +89,7 @@ where
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
     //~| ERROR the parameter type `T` may not live long enough
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
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 898c995e09b..b84ee4de5a3 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
@@ -40,11 +40,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |
    = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`...
 
-error: argument requires that data must outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-closure.rs:55:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-closure.rs:51:1
@@ -54,7 +54,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | | {
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
@@ -88,11 +88,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |
    = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
 
-error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-closure.rs:67:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-closure.rs:62:1
@@ -102,7 +102,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | |     'a: 'a,
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
@@ -137,11 +137,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |
    = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`...
 
-error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-closure.rs:89:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-closure.rs:74:1
@@ -151,7 +151,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | |     T::AssocType: 'a,
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs
index da76193459b..6317d6eca1f 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs
@@ -46,7 +46,7 @@ where
 {
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
@@ -57,7 +57,7 @@ where
 {
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
@@ -78,7 +78,7 @@ where
 
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[rustc_regions]
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 be11c6249f0..42ecd6f9860 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
@@ -31,11 +31,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 3
    = note: where '_#1r: '_#2r
 
-error: argument requires that data must outlive free region `ReFree(DefId(0/0:8 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(1:16), 'a))`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-trait-bound-closure.rs:47:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:43:1
@@ -45,7 +45,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | | {
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
@@ -70,11 +70,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 4
    = note: where '_#2r: '_#3r
 
-error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-trait-bound-closure.rs:58:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:53:1
@@ -84,7 +84,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | |     'a: 'a,
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
@@ -110,11 +110,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 4
    = note: where '_#2r: '_#3r
 
-error: argument requires that data must outlive free region `ReEarlyBound(0, 'a)`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-one-region-trait-bound-closure.rs:79:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-one-region-trait-bound-closure.rs:64:1
@@ -124,7 +124,7 @@ LL | | where
 LL | |     T: Anything<'b>,
 LL | |     T::AssocType: 'a,
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
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 5e481a9626f..2552054fd5f 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
@@ -107,7 +107,7 @@ where
 {
     with_signature(cell, t, |cell, t| require(cell, t));
     //~^ WARNING not reporting region error due to nll
-    //~| ERROR argument requires that data must outlive free region
+    //~| ERROR
 }
 
 #[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 546384e8545..b0f823ad3d5 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
@@ -239,11 +239,11 @@ LL |     with_signature(cell, t, |cell, t| require(cell, t));
    = note: number of external vids: 3
    = note: where <T as Anything<ReClosureBound('_#1r), ReClosureBound('_#1r)>>::AssocType: '_#2r
 
-error: argument requires that data must outlive free region `ReFree(DefId(0/0:13 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]), BrNamed(crate0:DefIndex(1:43), 'a))`
+error: unsatisfied lifetime constraints
   --> $DIR/projection-two-region-trait-bound-closure.rs:108:5
    |
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
 
 note: No external requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:104:1
@@ -253,7 +253,7 @@ LL | | where
 LL | |     T: Anything<'b, 'b>,
 LL | | {
 ...  |
-LL | |     //~| ERROR argument requires that data must outlive free region
+LL | |     //~| ERROR
 LL | | }
    | |_^
    |
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 49f9044b19b..04c3ed2d6ee 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr
@@ -22,11 +22,14 @@ warning: not reporting region error due to nll
 LL |     Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
-error: cast requires that data must outlive free region `'static`
+error: unsatisfied lifetime constraints
   --> $DIR/dyn-trait-underscore.rs:18:5
    |
+LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
+   |         ----- lifetime `'1` appears in this argument
+LL |     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
 LL |     Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
 
 error: aborting due to previous error