about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2020-05-30 23:08:42 +0200
committerGitHub <noreply@github.com>2020-05-30 23:08:42 +0200
commitf1661d23e386ecd2d2ebb7990fa4cb459b2896f6 (patch)
tree80d3c14e31f5f13ff465dc2c09cfee19ed8f7839 /src
parent74e80468347471779be6060d8d7d6d04e98e467f (diff)
parent83f6f2235892853c152d08551975525b7ae79914 (diff)
downloadrust-f1661d23e386ecd2d2ebb7990fa4cb459b2896f6.tar.gz
rust-f1661d23e386ecd2d2ebb7990fa4cb459b2896f6.zip
Rollup merge of #72543 - estebank:opaque-missing-lts-in-fn, r=nikomatsakis
Account for missing lifetime in opaque and trait object return types

When encountering an opaque closure return type that needs to bound a
lifetime to the function's arguments, including borrows and type params,
provide appropriate suggestions that lead to working code.

Get the user from

```rust
fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
where
    G: Get<T>
{
    move || {
        *dest = g.get();
    }
}
```

to

```rust
fn foo<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() +'a
where
    G: Get<T>
{
    move || {
        *dest = g.get();
    }
}
```
Diffstat (limited to 'src')
-rw-r--r--src/librustc_infer/infer/error_reporting/mod.rs170
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs6
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs2
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs37
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs83
-rw-r--r--src/librustc_infer/infer/error_reporting/note.rs59
-rw-r--r--src/librustc_middle/ty/context.rs101
-rw-r--r--src/librustc_middle/ty/diagnostics.rs19
-rw-r--r--src/test/ui/async-await/issues/issue-62097.stderr13
-rw-r--r--src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr8
-rw-r--r--src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr8
-rw-r--r--src/test/ui/generic-associated-types/impl_bounds.stderr6
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr56
-rw-r--r--src/test/ui/impl-trait/static-return-lifetime-infered.stderr32
-rw-r--r--src/test/ui/impl-trait/type_parameters_captured.stderr8
-rw-r--r--src/test/ui/issues/issue-16922.nll.stderr10
-rw-r--r--src/test/ui/issues/issue-16922.rs2
-rw-r--r--src/test/ui/issues/issue-16922.stderr17
-rw-r--r--src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr46
-rw-r--r--src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr6
-rw-r--r--src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr6
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr6
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default-from-box-error.rs2
-rw-r--r--src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr11
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr10
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.rs9
-rw-r--r--src/test/ui/regions/region-object-lifetime-in-coercion.stderr30
-rw-r--r--src/test/ui/regions/regions-close-associated-type-into-object.stderr24
-rw-r--r--src/test/ui/regions/regions-close-object-into-object-5.stderr48
-rw-r--r--src/test/ui/regions/regions-close-over-type-parameter-1.stderr16
-rw-r--r--src/test/ui/regions/regions-close-param-into-object.stderr32
-rw-r--r--src/test/ui/regions/regions-enum-not-wf.stderr35
-rw-r--r--src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr8
-rw-r--r--src/test/ui/regions/regions-infer-bound-from-trait-self.stderr6
-rw-r--r--src/test/ui/regions/regions-infer-bound-from-trait.stderr16
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr8
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr35
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr16
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr13
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr16
-rw-r--r--src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr115
-rw-r--r--src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs110
-rw-r--r--src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr126
-rw-r--r--src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr8
-rw-r--r--src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr8
-rw-r--r--src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr31
-rw-r--r--src/test/ui/wf/wf-impl-associated-type-region.stderr8
-rw-r--r--src/test/ui/wf/wf-in-fn-type-static.stderr16
-rw-r--r--src/test/ui/wf/wf-in-obj-type-static.stderr8
-rw-r--r--src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr16
-rw-r--r--src/test/ui/wf/wf-trait-associated-type-region.stderr6
51 files changed, 834 insertions, 654 deletions
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index ae901982817..a59a91e3005 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -60,7 +60,7 @@ use rustc_errors::{pluralize, struct_span_err};
 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_hir::Node;
+use rustc_hir::{Item, ItemKind, Node};
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{
     self,
@@ -1682,49 +1682,92 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         bound_kind: GenericKind<'tcx>,
         sub: Region<'tcx>,
     ) -> DiagnosticBuilder<'a> {
+        let hir = &self.tcx.hir();
         // Attempt to obtain the span of the parameter so we can
         // suggest adding an explicit lifetime bound to it.
-        let type_param_span = match (self.in_progress_tables, bound_kind) {
-            (Some(ref table), GenericKind::Param(ref param)) => {
-                let table_owner = table.borrow().hir_owner;
-                table_owner.and_then(|table_owner| {
-                    let generics = self.tcx.generics_of(table_owner.to_def_id());
-                    // Account for the case where `param` corresponds to `Self`,
-                    // which doesn't have the expected type argument.
-                    if !(generics.has_self && param.index == 0) {
-                        let type_param = generics.type_param(param, self.tcx);
-                        let hir = &self.tcx.hir();
-                        type_param.def_id.as_local().map(|def_id| {
-                            // Get the `hir::Param` to verify whether it already has any bounds.
-                            // We do this to avoid suggesting code that ends up as `T: 'a'b`,
-                            // instead we suggest `T: 'a + 'b` in that case.
-                            let id = hir.as_local_hir_id(def_id);
-                            let mut has_bounds = false;
-                            if let Node::GenericParam(param) = hir.get(id) {
-                                has_bounds = !param.bounds.is_empty();
-                            }
-                            let sp = hir.span(id);
-                            // `sp` only covers `T`, change it so that it covers
-                            // `T:` when appropriate
-                            let is_impl_trait = bound_kind.to_string().starts_with("impl ");
-                            let sp = if has_bounds && !is_impl_trait {
-                                sp.to(self
-                                    .tcx
-                                    .sess
-                                    .source_map()
-                                    .next_point(self.tcx.sess.source_map().next_point(sp)))
-                            } else {
-                                sp
-                            };
-                            (sp, has_bounds, is_impl_trait)
-                        })
+        let generics =
+            self.in_progress_tables.and_then(|table| table.borrow().hir_owner).map(|table_owner| {
+                let hir_id = hir.as_local_hir_id(table_owner);
+                let parent_id = hir.get_parent_item(hir_id);
+                (
+                    // Parent item could be a `mod`, so we check the HIR before calling:
+                    if let Some(Node::Item(Item {
+                        kind: ItemKind::Trait(..) | ItemKind::Impl { .. },
+                        ..
+                    })) = hir.find(parent_id)
+                    {
+                        Some(self.tcx.generics_of(hir.local_def_id(parent_id).to_def_id()))
                     } else {
                         None
-                    }
-                })
+                    },
+                    self.tcx.generics_of(table_owner.to_def_id()),
+                )
+            });
+        let type_param_span = match (generics, bound_kind) {
+            (Some((_, ref generics)), GenericKind::Param(ref param)) => {
+                // Account for the case where `param` corresponds to `Self`,
+                // which doesn't have the expected type argument.
+                if !(generics.has_self && param.index == 0) {
+                    let type_param = generics.type_param(param, self.tcx);
+                    type_param.def_id.as_local().map(|def_id| {
+                        // Get the `hir::Param` to verify whether it already has any bounds.
+                        // We do this to avoid suggesting code that ends up as `T: 'a'b`,
+                        // instead we suggest `T: 'a + 'b` in that case.
+                        let id = hir.as_local_hir_id(def_id);
+                        let mut has_bounds = false;
+                        if let Node::GenericParam(param) = hir.get(id) {
+                            has_bounds = !param.bounds.is_empty();
+                        }
+                        let sp = hir.span(id);
+                        // `sp` only covers `T`, change it so that it covers
+                        // `T:` when appropriate
+                        let is_impl_trait = bound_kind.to_string().starts_with("impl ");
+                        let sp = if has_bounds && !is_impl_trait {
+                            sp.to(self
+                                .tcx
+                                .sess
+                                .source_map()
+                                .next_point(self.tcx.sess.source_map().next_point(sp)))
+                        } else {
+                            sp
+                        };
+                        (sp, has_bounds, is_impl_trait)
+                    })
+                } else {
+                    None
+                }
             }
             _ => None,
         };
+        let new_lt = generics
+            .as_ref()
+            .and_then(|(parent_g, g)| {
+                let possible: Vec<_> = (b'a'..=b'z').map(|c| format!("'{}", c as char)).collect();
+                let mut lts_names = g
+                    .params
+                    .iter()
+                    .filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime))
+                    .map(|p| p.name.as_str())
+                    .collect::<Vec<_>>();
+                if let Some(g) = parent_g {
+                    lts_names.extend(
+                        g.params
+                            .iter()
+                            .filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime))
+                            .map(|p| p.name.as_str()),
+                    );
+                }
+                let lts = lts_names.iter().map(|s| -> &str { &*s }).collect::<Vec<_>>();
+                possible.into_iter().find(|candidate| !lts.contains(&candidate.as_str()))
+            })
+            .unwrap_or("'lt".to_string());
+        let add_lt_sugg = generics
+            .as_ref()
+            .and_then(|(_, g)| g.params.first())
+            .and_then(|param| param.def_id.as_local())
+            .map(|def_id| {
+                (hir.span(hir.as_local_hir_id(def_id)).shrink_to_lo(), format!("{}, ", new_lt))
+            });
 
         let labeled_user_string = match bound_kind {
             GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
@@ -1781,6 +1824,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             }
         }
 
+        let new_binding_suggestion =
+            |err: &mut DiagnosticBuilder<'tcx>,
+             type_param_span: Option<(Span, bool, bool)>,
+             bound_kind: GenericKind<'tcx>| {
+                let msg = "consider introducing an explicit lifetime bound";
+                if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span {
+                    let suggestion = if is_impl_trait {
+                        (sp.shrink_to_hi(), format!(" + {}", new_lt))
+                    } else {
+                        let tail = if has_lifetimes { " +" } else { "" };
+                        (sp, format!("{}: {}{}", bound_kind, new_lt, tail))
+                    };
+                    let mut sugg =
+                        vec![suggestion, (span.shrink_to_hi(), format!(" + {}", new_lt))];
+                    if let Some(lt) = add_lt_sugg {
+                        sugg.push(lt);
+                        sugg.rotate_right(1);
+                    }
+                    // `MaybeIncorrect` due to issue #41966.
+                    err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
+                }
+            };
+
         let mut err = match *sub {
             ty::ReEarlyBound(ty::EarlyBoundRegion { name, .. })
             | ty::ReFree(ty::FreeRegion { bound_region: ty::BrNamed(_, name), .. }) => {
@@ -1822,10 +1888,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     "{} may not live long enough",
                     labeled_user_string
                 );
-                err.help(&format!(
-                    "consider adding an explicit lifetime bound for `{}`",
-                    bound_kind
-                ));
                 note_and_explain_region(
                     self.tcx,
                     &mut err,
@@ -1833,6 +1895,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     sub,
                     "...",
                 );
+                if let Some(infer::RelateParamBound(_, t)) = origin {
+                    let t = self.resolve_vars_if_possible(&t);
+                    match t.kind {
+                        // We've got:
+                        // fn get_later<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+                        // suggest:
+                        // fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+                        ty::Closure(_, _substs) | ty::Opaque(_, _substs) => {
+                            new_binding_suggestion(&mut err, type_param_span, bound_kind);
+                        }
+                        _ => {
+                            binding_suggestion(&mut err, type_param_span, bound_kind, new_lt);
+                        }
+                    }
+                }
                 err
             }
         };
@@ -1861,14 +1938,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             "...",
         );
 
+        debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
+        debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
+        debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
+        debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
+        debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);
+
         if let (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) =
             (&sup_origin, &sub_origin)
         {
-            debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
-            debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
-            debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
-            debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
-            debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);
             debug!("report_sub_sup_conflict: sup_trace={:?}", sup_trace);
             debug!("report_sub_sup_conflict: sub_trace={:?}", sub_trace);
             debug!("report_sub_sup_conflict: sup_trace.values={:?}", sup_trace.values);
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
index d206a30d526..7ab18e54f7e 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -121,16 +121,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             (Some(ret_span), _) => (
                 ty_sub.span,
                 ret_span,
-                "this parameter and the return type are declared \
-                 with different lifetimes..."
+                "this parameter and the return type are declared with different lifetimes..."
                     .to_owned(),
                 format!("...but data{} is returned here", span_label_var1),
             ),
             (_, Some(ret_span)) => (
                 ty_sup.span,
                 ret_span,
-                "this parameter and the return type are declared \
-                 with different lifetimes..."
+                "this parameter and the return type are declared with different lifetimes..."
                     .to_owned(),
                 format!("...but data{} is returned here", span_label_var1),
             ),
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
index efe52689550..cc8f1816bc3 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/mod.rs
@@ -55,9 +55,9 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
                 diag.emit();
                 ErrorReported
             })
+            .or_else(|| self.try_report_impl_not_conforming_to_trait())
             .or_else(|| self.try_report_anon_anon_conflict())
             .or_else(|| self.try_report_static_impl_trait())
-            .or_else(|| self.try_report_impl_not_conforming_to_trait())
     }
 
     pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index b85a4cae2e4..acaf4746992 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -21,8 +21,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         // where the anonymous region appears (there must always be one; we
         // only introduced anonymous regions in parameters) as well as a
         // version new_ty of its type where the anonymous region is replaced
-        // with the named one.//scope_def_id
-        let (named, anon, anon_param_info, region_info) = if self.is_named_region(sub)
+        // with the named one.
+        let (named, anon, anon_param_info, region_info) = if sub.has_name()
             && self.tcx().is_suitable_region(sup).is_some()
             && self.find_param_with_region(sup, sub).is_some()
         {
@@ -32,7 +32,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                 self.find_param_with_region(sup, sub).unwrap(),
                 self.tcx().is_suitable_region(sup).unwrap(),
             )
-        } else if self.is_named_region(sup)
+        } else if sup.has_name()
             && self.tcx().is_suitable_region(sub).is_some()
             && self.find_param_with_region(sub, sup).is_some()
         {
@@ -74,15 +74,21 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         }
 
         if let Some((_, fndecl)) = self.find_anon_type(anon, &br) {
-            if self.is_return_type_anon(scope_def_id, br, fndecl).is_some()
-                || self.is_self_anon(is_first, scope_def_id)
-            {
+            let is_self_anon = self.is_self_anon(is_first, scope_def_id);
+            if is_self_anon {
                 return None;
             }
+
             if let FnRetTy::Return(ty) = &fndecl.output {
-                if let (TyKind::Def(_, _), ty::ReStatic) = (&ty.kind, sub) {
-                    // This is an impl Trait return that evaluates de need of 'static.
-                    // We handle this case better in `static_impl_trait`.
+                let mut v = ty::TraitObjectVisitor(vec![]);
+                rustc_hir::intravisit::walk_ty(&mut v, ty);
+
+                debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
+                if sub == &ty::ReStatic && (matches!(ty.kind, TyKind::Def(_, _)) || v.0.len() == 1)
+                {
+                    debug!("try_report_named_anon_conflict: impl Trait + 'static");
+                    // This is an `impl Trait` or `dyn Trait` return that evaluates de need of
+                    // `'static`. We handle this case better in `static_impl_trait`.
                     return None;
                 }
             }
@@ -114,17 +120,4 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
 
         Some(diag)
     }
-
-    // This method returns whether the given Region is Named
-    pub(super) fn is_named_region(&self, region: ty::Region<'tcx>) -> bool {
-        match *region {
-            ty::ReStatic => true,
-            ty::ReFree(ref free_region) => match free_region.bound_region {
-                ty::BrNamed(..) => true,
-                _ => false,
-            },
-            ty::ReEarlyBound(ebr) => ebr.has_name(),
-            _ => false,
-        }
-    }
 }
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 7f3ec852e41..f4c86ddae60 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -4,7 +4,7 @@ use crate::infer::error_reporting::msg_span_from_free_region;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use rustc_errors::{Applicability, ErrorReported};
-use rustc_middle::ty::{BoundRegion, FreeRegion, RegionKind};
+use rustc_middle::ty::RegionKind;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when the return type is a static impl Trait.
@@ -20,48 +20,59 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             ) = error.clone()
             {
                 let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
-                let return_ty = self.tcx().return_type_impl_trait(anon_reg_sup.def_id);
-                if sub_r == &RegionKind::ReStatic && return_ty.is_some() {
+                let (fn_return_span, is_dyn) =
+                    self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?;
+                if sub_r == &RegionKind::ReStatic {
                     let sp = var_origin.span();
                     let return_sp = sub_origin.span();
                     let mut err =
                         self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime");
-                    err.span_label(
-                        return_sp,
-                        "this return type evaluates to the `'static` lifetime...",
-                    );
-                    err.span_label(sup_origin.span(), "...but this borrow...");
+                    let param_info = self.find_param_with_region(sup_r, sub_r)?;
+                    err.span_label(param_info.param_ty_span, "data with this lifetime...");
 
-                    let (lifetime, lt_sp_opt) = msg_span_from_free_region(self.tcx(), sup_r);
-                    if let Some(lifetime_sp) = lt_sp_opt {
-                        err.span_note(lifetime_sp, &format!("...can't outlive {}", lifetime));
-                    }
-
-                    let lifetime_name = match sup_r {
-                        RegionKind::ReFree(FreeRegion {
-                            bound_region: BoundRegion::BrNamed(_, ref name),
-                            ..
-                        }) => name.to_string(),
-                        _ => "'_".to_owned(),
-                    };
-                    let fn_return_span = return_ty.unwrap().1;
-                    if let Ok(snippet) =
-                        self.tcx().sess.source_map().span_to_snippet(fn_return_span)
+                    // We try to make the output have fewer overlapping spans if possible.
+                    if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span()))
+                        && sup_origin.span() != return_sp
                     {
-                        // only apply this suggestion onto functions with
-                        // explicit non-desugar'able return.
-                        if fn_return_span.desugaring_kind().is_none() {
-                            err.span_suggestion(
-                                fn_return_span,
-                                &format!(
-                                    "you can add a bound to the return type to make it last \
-                                 less than `'static` and match {}",
-                                    lifetime,
-                                ),
-                                format!("{} + {}", snippet, lifetime_name),
-                                Applicability::Unspecified,
-                            );
+                        // FIXME: account for `async fn` like in `async-await/issues/issue-62097.rs`
+
+                        // Customize the spans and labels depending on their relative order so
+                        // that split sentences flow correctly.
+                        if sup_origin.span().shrink_to_hi() <= return_sp.shrink_to_lo() {
+                            err.span_label(sup_origin.span(), "...is captured here...");
+                            err.span_label(return_sp, "...and required to be `'static` by this");
+                        } else {
+                            err.span_label(return_sp, "...is required to be `'static` by this...");
+                            err.span_label(sup_origin.span(), "...and is captured here");
                         }
+                    } else {
+                        err.span_label(
+                            return_sp,
+                            "...is captured and required to be `'static` here",
+                        );
+                    }
+
+                    let (lifetime, _) = msg_span_from_free_region(self.tcx(), sup_r);
+
+                    let lifetime_name =
+                        if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() };
+                    // only apply this suggestion onto functions with
+                    // explicit non-desugar'able return.
+                    if fn_return_span.desugaring_kind().is_none() {
+                        let msg = format!(
+                            "to permit non-static references in {} `{} Trait` value, you can add \
+                             an explicit bound for {}",
+                            if is_dyn { "a" } else { "an" },
+                            if is_dyn { "dyn" } else { "impl" },
+                            lifetime,
+                        );
+                        // FIXME: account for the need of parens in `&(dyn Trait + '_)`
+                        err.span_suggestion_verbose(
+                            fn_return_span.shrink_to_hi(),
+                            &msg,
+                            format!(" + {}", lifetime_name),
+                            Applicability::MaybeIncorrect,
+                        );
                     }
                     err.emit();
                     return Some(ErrorReported);
diff --git a/src/librustc_infer/infer/error_reporting/note.rs b/src/librustc_infer/infer/error_reporting/note.rs
index 8fbb89da5af..9ac27030ade 100644
--- a/src/librustc_infer/infer/error_reporting/note.rs
+++ b/src/librustc_infer/infer/error_reporting/note.rs
@@ -10,10 +10,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         err: &mut DiagnosticBuilder<'_>,
         origin: &SubregionOrigin<'tcx>,
     ) {
+        let mut label_or_note = |span, msg| {
+            let sub_count = err.children.iter().filter(|d| d.span.is_dummy()).count();
+            let expanded_sub_count = err.children.iter().filter(|d| !d.span.is_dummy()).count();
+            let span_is_primary = err.span.primary_spans().iter().all(|&sp| sp == span);
+            if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
+                err.span_label(span, msg);
+            } else if span_is_primary && expanded_sub_count == 0 {
+                err.note(msg);
+            } else {
+                err.span_note(span, msg);
+            }
+        };
         match *origin {
             infer::Subtype(ref trace) => {
                 if let Some((expected, found)) = self.values_str(&trace.values) {
-                    err.span_note(
+                    label_or_note(
                         trace.cause.span,
                         &format!("...so that the {}", trace.cause.as_requirement_str()),
                     );
@@ -24,27 +36,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     // handling of region checking when type errors are present is
                     // *terrible*.
 
-                    err.span_note(
+                    label_or_note(
                         trace.cause.span,
                         &format!("...so that {}", trace.cause.as_requirement_str()),
                     );
                 }
             }
             infer::Reborrow(span) => {
-                err.span_note(span, "...so that reference does not outlive borrowed content");
+                label_or_note(span, "...so that reference does not outlive borrowed content");
             }
             infer::ReborrowUpvar(span, ref upvar_id) => {
                 let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
-                err.span_note(span, &format!("...so that closure can access `{}`", var_name));
+                label_or_note(span, &format!("...so that closure can access `{}`", var_name));
             }
             infer::RelateObjectBound(span) => {
-                err.span_note(span, "...so that it can be closed over into an object");
+                label_or_note(span, "...so that it can be closed over into an object");
             }
             infer::CallReturn(span) => {
-                err.span_note(span, "...so that return value is valid for the call");
+                label_or_note(span, "...so that return value is valid for the call");
             }
             infer::DataBorrowed(ty, span) => {
-                err.span_note(
+                label_or_note(
                     span,
                     &format!(
                         "...so that the type `{}` is not borrowed for too long",
@@ -53,36 +65,33 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
             }
             infer::ReferenceOutlivesReferent(ty, span) => {
-                err.span_note(
+                label_or_note(
                     span,
                     &format!(
-                        "...so that the reference type `{}` does not outlive the \
-                                        data it points at",
+                        "...so that the reference type `{}` does not outlive the data it points at",
                         self.ty_to_string(ty)
                     ),
                 );
             }
             infer::RelateParamBound(span, t) => {
-                err.span_note(
+                label_or_note(
                     span,
                     &format!(
-                        "...so that the type `{}` will meet its required \
-                                        lifetime bounds",
+                        "...so that the type `{}` will meet its required lifetime bounds",
                         self.ty_to_string(t)
                     ),
                 );
             }
             infer::RelateRegionParamBound(span) => {
-                err.span_note(
+                label_or_note(
                     span,
                     "...so that the declared lifetime parameter bounds are satisfied",
                 );
             }
             infer::CompareImplMethodObligation { span, .. } => {
-                err.span_note(
+                label_or_note(
                     span,
-                    "...so that the definition in impl matches the definition from the \
-                               trait",
+                    "...so that the definition in impl matches the definition from the trait",
                 );
             }
         }
@@ -113,8 +122,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     self.tcx.sess,
                     span,
                     E0312,
-                    "lifetime of reference outlives lifetime of \
-                                                borrowed content..."
+                    "lifetime of reference outlives lifetime of borrowed content..."
                 );
                 note_and_explain_region(
                     self.tcx,
@@ -138,8 +146,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     self.tcx.sess,
                     span,
                     E0313,
-                    "lifetime of borrowed pointer outlives lifetime \
-                                                of captured variable `{}`...",
+                    "lifetime of borrowed pointer outlives lifetime of captured variable `{}`...",
                     var_name
                 );
                 note_and_explain_region(
@@ -163,8 +170,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     self.tcx.sess,
                     span,
                     E0476,
-                    "lifetime of the source pointer does not outlive \
-                                                lifetime bound of the object type"
+                    "lifetime of the source pointer does not outlive lifetime bound of the \
+                     object type"
                 );
                 note_and_explain_region(self.tcx, &mut err, "object type is valid for ", sub, "");
                 note_and_explain_region(
@@ -181,8 +188,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     self.tcx.sess,
                     span,
                     E0477,
-                    "the type `{}` does not fulfill the required \
-                                                lifetime",
+                    "the type `{}` does not fulfill the required lifetime",
                     self.ty_to_string(ty)
                 );
                 match *sub {
@@ -217,8 +223,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     self.tcx.sess,
                     span,
                     E0482,
-                    "lifetime of return value does not outlive the \
-                                                function call"
+                    "lifetime of return value does not outlive the function call"
                 );
                 note_and_explain_region(
                     self.tcx,
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index 3a08d202ea3..c9d240a5da9 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -1,38 +1,27 @@
 //! Type context book-keeping.
 
 use crate::arena::Arena;
-use crate::dep_graph::DepGraph;
-use crate::dep_graph::{self, DepConstructor};
+use crate::dep_graph::{self, DepConstructor, DepGraph};
 use crate::hir::exports::Export;
 use crate::ich::{NodeIdHashingMode, StableHashingContext};
 use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
-use crate::lint::LintDiagnosticBuilder;
-use crate::lint::{struct_lint_level, LintSource};
+use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintSource};
 use crate::middle;
-use crate::middle::cstore::CrateStoreDyn;
-use crate::middle::cstore::EncodedMetadata;
+use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata};
 use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
 use crate::middle::stability;
-use crate::mir::interpret::{Allocation, ConstValue, Scalar};
-use crate::mir::{interpret, Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
+use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
+use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
 use crate::traits;
-use crate::ty::query;
 use crate::ty::steal::Steal;
-use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
-use crate::ty::subst::{GenericArgKind, UserSubsts};
-use crate::ty::CanonicalPolyFnSig;
-use crate::ty::GenericParamDefKind;
-use crate::ty::RegionKind;
-use crate::ty::ReprOptions;
+use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
 use crate::ty::TyKind::*;
-use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
-use crate::ty::{AdtDef, AdtKind, Const, Region};
-use crate::ty::{BindingMode, BoundVar};
-use crate::ty::{ConstVid, FloatVar, FloatVid, IntVar, IntVid, TyVar, TyVid};
-use crate::ty::{ExistentialPredicate, Predicate, PredicateKind};
-use crate::ty::{InferConst, ParamConst};
-use crate::ty::{InferTy, ParamTy, PolyFnSig, ProjectionTy};
-use crate::ty::{List, TyKind, TyS};
+use crate::ty::{
+    self, query, AdtDef, AdtKind, BindingMode, BoundVar, CanonicalPolyFnSig, Const, ConstVid,
+    DefIdTree, ExistentialPredicate, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy,
+    IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, ProjectionTy,
+    Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut,
+};
 use rustc_ast::ast;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_attr as attr;
@@ -48,10 +37,8 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
 use rustc_hir::definitions::{DefPathHash, Definitions};
-use rustc_hir::lang_items;
-use rustc_hir::lang_items::PanicLocationLangItem;
-use rustc_hir::{HirId, Node, TraitCandidate};
-use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet};
+use rustc_hir::lang_items::{self, PanicLocationLangItem};
+use rustc_hir::{HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_macros::HashStable;
 use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
@@ -1396,6 +1383,66 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
+    pub fn return_type_impl_or_dyn_trait(&self, scope_def_id: DefId) -> Option<(Span, bool)> {
+        let hir_id = self.hir().as_local_hir_id(scope_def_id.expect_local());
+        let hir_output = match self.hir().get(hir_id) {
+            Node::Item(hir::Item {
+                kind:
+                    ItemKind::Fn(
+                        hir::FnSig {
+                            decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
+                            ..
+                        },
+                        ..,
+                    ),
+                ..
+            })
+            | Node::ImplItem(hir::ImplItem {
+                kind:
+                    hir::ImplItemKind::Fn(
+                        hir::FnSig {
+                            decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
+                            ..
+                        },
+                        _,
+                    ),
+                ..
+            })
+            | Node::TraitItem(hir::TraitItem {
+                kind:
+                    hir::TraitItemKind::Fn(
+                        hir::FnSig {
+                            decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
+                            ..
+                        },
+                        _,
+                    ),
+                ..
+            }) => ty,
+            _ => return None,
+        };
+
+        let ret_ty = self.type_of(scope_def_id);
+        match ret_ty.kind {
+            ty::FnDef(_, _) => {
+                let sig = ret_ty.fn_sig(*self);
+                let output = self.erase_late_bound_regions(&sig.output());
+                if output.is_impl_trait() {
+                    let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
+                    Some((fn_decl.output.span(), false))
+                } else {
+                    let mut v = TraitObjectVisitor(vec![]);
+                    rustc_hir::intravisit::walk_ty(&mut v, hir_output);
+                    if v.0.len() == 1 {
+                        return Some((v.0[0], true));
+                    }
+                    None
+                }
+            }
+            _ => None,
+        }
+    }
+
     pub fn return_type_impl_trait(&self, scope_def_id: DefId) -> Option<(Ty<'tcx>, Span)> {
         // HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
         let hir_id = self.hir().as_local_hir_id(scope_def_id.expect_local());
diff --git a/src/librustc_middle/ty/diagnostics.rs b/src/librustc_middle/ty/diagnostics.rs
index 613d66d59c5..1403efb745b 100644
--- a/src/librustc_middle/ty/diagnostics.rs
+++ b/src/librustc_middle/ty/diagnostics.rs
@@ -249,3 +249,22 @@ pub fn suggest_constraining_type_param(
         true
     }
 }
+
+pub struct TraitObjectVisitor(pub Vec<rustc_span::Span>);
+impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor {
+    type Map = rustc_hir::intravisit::ErasedMap<'v>;
+
+    fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
+        hir::intravisit::NestedVisitorMap::None
+    }
+
+    fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
+        if let hir::TyKind::TraitObject(
+            _,
+            hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. },
+        ) = ty.kind
+        {
+            self.0.push(ty.span);
+        }
+    }
+}
diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr
index 94afccc06a9..af8fc2cd2ab 100644
--- a/src/test/ui/async-await/issues/issue-62097.stderr
+++ b/src/test/ui/async-await/issues/issue-62097.stderr
@@ -2,15 +2,12 @@ error: cannot infer an appropriate lifetime
   --> $DIR/issue-62097.rs:12:31
    |
 LL |     pub async fn run_dummy_fn(&self) {
-   |                               ^^^^^ ...but this borrow...
+   |                               ^^^^^
+   |                               |
+   |                               data with this lifetime...
+   |                               ...is captured here...
 LL |         foo(|| self.bar()).await;
-   |         --- this return type evaluates to the `'static` lifetime...
-   |
-note: ...can't outlive the lifetime `'_` as defined on the method body at 12:31
-  --> $DIR/issue-62097.rs:12:31
-   |
-LL |     pub async fn run_dummy_fn(&self) {
-   |                               ^
+   |         --- ...and required to be `'static` by this
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr b/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr
index 999a5839ba6..2dac4a22ae7 100644
--- a/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr
+++ b/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr
@@ -2,15 +2,9 @@ error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/builtin-superkinds-self-type.rs:10:16
    |
 LL | impl <T: Sync> Foo for T { }
-   |       --       ^^^
+   |       --       ^^^ ...so that the type `T` will meet its required lifetime bounds
    |       |
    |       help: consider adding an explicit lifetime bound...: `T: 'static +`
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/builtin-superkinds-self-type.rs:10:16
-   |
-LL | impl <T: Sync> Foo for T { }
-   |                ^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr b/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr
index fbc4e8abc42..2beeba8184a 100644
--- a/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr
+++ b/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr
@@ -4,13 +4,7 @@ error[E0310]: the parameter type `U` may not live long enough
 LL | struct Foo<U> {
    |            - help: consider adding an explicit lifetime bound...: `U: 'static`
 LL |     bar: Bar<U>
-   |     ^^^^^^^^^^^
-   |
-note: ...so that the type `U` will meet its required lifetime bounds
-  --> $DIR/feature-gate-infer_static_outlives_requirements.rs:5:5
-   |
-LL |     bar: Bar<U>
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr
index d5560c81337..e06977ebbe3 100644
--- a/src/test/ui/generic-associated-types/impl_bounds.stderr
+++ b/src/test/ui/generic-associated-types/impl_bounds.stderr
@@ -5,11 +5,7 @@ LL |     type A<'a> where Self: 'static = (&'a ());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `T: 'static`...
-note: ...so that the type `Fooy<T>` will meet its required lifetime bounds
-  --> $DIR/impl_bounds.rs:15:5
-   |
-LL |     type A<'a> where Self: 'static = (&'a ());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...so that the type `Fooy<T>` will meet its required lifetime bounds
 
 error[E0478]: lifetime bound not satisfied
   --> $DIR/impl_bounds.rs:17:5
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index cffa5ee8f14..d7dae6a08a7 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -2,55 +2,43 @@ error: cannot infer an appropriate lifetime
   --> $DIR/must_outlive_least_region_or_bound.rs:3:35
    |
 LL | fn elided(x: &i32) -> impl Copy { x }
-   |                       ---------   ^ ...but this borrow...
-   |                       |
-   |                       this return type evaluates to the `'static` lifetime...
+   |              ----     ---------   ^ ...and is captured here
+   |              |        |
+   |              |        ...is required to be `'static` by this...
+   |              data with this lifetime...
    |
-note: ...can't outlive the anonymous lifetime #1 defined on the function body at 3:1
-  --> $DIR/must_outlive_least_region_or_bound.rs:3:1
-   |
-LL | fn elided(x: &i32) -> impl Copy { x }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 3:1
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
    |
 LL | fn elided(x: &i32) -> impl Copy + '_ { x }
-   |                       ^^^^^^^^^^^^^^
+   |                                 ^^^^
 
 error: cannot infer an appropriate lifetime
   --> $DIR/must_outlive_least_region_or_bound.rs:6:44
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
-   |                                ---------   ^ ...but this borrow...
-   |                                |
-   |                                this return type evaluates to the `'static` lifetime...
+   |                    -------     ---------   ^ ...and is captured here
+   |                    |           |
+   |                    |           ...is required to be `'static` by this...
+   |                    data with this lifetime...
    |
-note: ...can't outlive the lifetime `'a` as defined on the function body at 6:13
-  --> $DIR/must_outlive_least_region_or_bound.rs:6:13
-   |
-LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
-   |             ^^
-help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 6:13
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 6:13
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
-   |                                ^^^^^^^^^^^^^^
+   |                                          ^^^^
 
 error: cannot infer an appropriate lifetime
   --> $DIR/must_outlive_least_region_or_bound.rs:12:69
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
-   |                                  --------------------------------   ^ ...but this borrow...
-   |                                  |
-   |                                  this return type evaluates to the `'static` lifetime...
-   |
-note: ...can't outlive the lifetime `'a` as defined on the function body at 12:15
-  --> $DIR/must_outlive_least_region_or_bound.rs:12:15
+   |                      -------     --------------------------------   ^ ...and is captured here
+   |                      |           |
+   |                      |           ...is required to be `'static` by this...
+   |                      data with this lifetime...
    |
-LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
-   |               ^^
-help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 12:15
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:15
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x }
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                                                   ^^^^
 
 error[E0623]: lifetime mismatch
   --> $DIR/must_outlive_least_region_or_bound.rs:17:61
@@ -65,15 +53,9 @@ error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/must_outlive_least_region_or_bound.rs:22:51
    |
 LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
-   |                                 --                ^^^^^^^^^^^^^^^^^^^^
+   |                                 --                ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
    |                                 |
    |                                 help: consider adding an explicit lifetime bound...: `T: 'static +`
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/must_outlive_least_region_or_bound.rs:22:51
-   |
-LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
-   |                                                   ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
index e550be19174..1c3a5979ee5 100644
--- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
+++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
@@ -2,43 +2,35 @@ error: cannot infer an appropriate lifetime
   --> $DIR/static-return-lifetime-infered.rs:7:16
    |
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
-   |                                   ----------------------- this return type evaluates to the `'static` lifetime...
+   |                         -----     ----------------------- ...is required to be `'static` by this...
+   |                         |
+   |                         data with this lifetime...
 LL |         self.x.iter().map(|a| a.0)
    |         ------ ^^^^
    |         |
-   |         ...but this borrow...
+   |         ...and is captured here
    |
-note: ...can't outlive the anonymous lifetime #1 defined on the method body at 6:5
-  --> $DIR/static-return-lifetime-infered.rs:6:5
-   |
-LL | /     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
-LL | |         self.x.iter().map(|a| a.0)
-LL | |     }
-   | |_____^
-help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5
    |
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                                           ^^^^
 
 error: cannot infer an appropriate lifetime
   --> $DIR/static-return-lifetime-infered.rs:11:16
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
-   |                                     ----------------------- this return type evaluates to the `'static` lifetime...
+   |                        --------     ----------------------- ...is required to be `'static` by this...
+   |                        |
+   |                        data with this lifetime...
 LL |         self.x.iter().map(|a| a.0)
    |         ------ ^^^^
    |         |
-   |         ...but this borrow...
-   |
-note: ...can't outlive the lifetime `'a` as defined on the method body at 10:20
-  --> $DIR/static-return-lifetime-infered.rs:10:20
+   |         ...and is captured here
    |
-LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
-   |                    ^^
-help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the method body at 10:20
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the method body at 10:20
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                                             ^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/impl-trait/type_parameters_captured.stderr b/src/test/ui/impl-trait/type_parameters_captured.stderr
index 34f0f7f1d73..40e50b9922f 100644
--- a/src/test/ui/impl-trait/type_parameters_captured.stderr
+++ b/src/test/ui/impl-trait/type_parameters_captured.stderr
@@ -2,15 +2,9 @@ error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/type_parameters_captured.rs:7:20
    |
 LL | fn foo<T>(x: T) -> impl Any + 'static {
-   |        -           ^^^^^^^^^^^^^^^^^^
+   |        -           ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
    |        |
    |        help: consider adding an explicit lifetime bound...: `T: 'static`
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/type_parameters_captured.rs:7:20
-   |
-LL | fn foo<T>(x: T) -> impl Any + 'static {
-   |                    ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-16922.nll.stderr b/src/test/ui/issues/issue-16922.nll.stderr
new file mode 100644
index 00000000000..7f4f5b22eb3
--- /dev/null
+++ b/src/test/ui/issues/issue-16922.nll.stderr
@@ -0,0 +1,10 @@
+error: lifetime may not live long enough
+  --> $DIR/issue-16922.rs:4:5
+   |
+LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
+   |                       - let's call the lifetime of this reference `'1`
+LL |     Box::new(value) as Box<dyn Any>
+   |     ^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-16922.rs b/src/test/ui/issues/issue-16922.rs
index 10a5cccbcee..827163ef83c 100644
--- a/src/test/ui/issues/issue-16922.rs
+++ b/src/test/ui/issues/issue-16922.rs
@@ -2,7 +2,7 @@ use std::any::Any;
 
 fn foo<T: Any>(value: &T) -> Box<dyn Any> {
     Box::new(value) as Box<dyn Any>
-    //~^ ERROR explicit lifetime required in the type of `value` [E0621]
+    //~^ ERROR cannot infer an appropriate lifetime
 }
 
 fn main() {
diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr
index 4e3d3ecb9c0..02d33aae023 100644
--- a/src/test/ui/issues/issue-16922.stderr
+++ b/src/test/ui/issues/issue-16922.stderr
@@ -1,11 +1,18 @@
-error[E0621]: explicit lifetime required in the type of `value`
-  --> $DIR/issue-16922.rs:4:5
+error: cannot infer an appropriate lifetime
+  --> $DIR/issue-16922.rs:4:14
    |
 LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
-   |                       -- help: add explicit lifetime `'static` to the type of `value`: `&'static T`
+   |                       -- data with this lifetime...
 LL |     Box::new(value) as Box<dyn Any>
-   |     ^^^^^^^^^^^^^^^ lifetime `'static` required
+   |     ---------^^^^^-
+   |     |        |
+   |     |        ...and is captured here
+   |     ...is required to be `'static` by this...
+   |
+help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
+   |
+LL | fn foo<T: Any>(value: &T) -> Box<dyn Any + '_> {
+   |                                          ^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0621`.
diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
index e60c461743c..d682478db0e 100644
--- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
+++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
@@ -4,13 +4,7 @@ error[E0310]: the parameter type `T` may not live long enough
 LL | struct Foo<T> {
    |            - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     foo: &'static T
-   |     ^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'static T` does not outlive the data it points at
-  --> $DIR/lifetime-doesnt-live-long-enough.rs:19:5
-   |
-LL |     foo: &'static T
-   |     ^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
 
 error[E0309]: the parameter type `K` may not live long enough
   --> $DIR/lifetime-doesnt-live-long-enough.rs:24:19
@@ -18,13 +12,7 @@ error[E0309]: the parameter type `K` may not live long enough
 LL | trait X<K>: Sized {
    |         - help: consider adding an explicit lifetime bound...: `K: 'a`
 LL |     fn foo<'a, L: X<&'a Nested<K>>>();
-   |                   ^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
-  --> $DIR/lifetime-doesnt-live-long-enough.rs:24:19
-   |
-LL |     fn foo<'a, L: X<&'a Nested<K>>>();
-   |                   ^^^^^^^^^^^^^^^^
+   |                   ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
 
 error[E0309]: the parameter type `Self` may not live long enough
   --> $DIR/lifetime-doesnt-live-long-enough.rs:28:19
@@ -33,25 +21,15 @@ LL |     fn bar<'a, L: X<&'a Nested<Self>>>();
    |                   ^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `Self: 'a`...
-note: ...so that the reference type `&'a Nested<Self>` does not outlive the data it points at
-  --> $DIR/lifetime-doesnt-live-long-enough.rs:28:19
-   |
-LL |     fn bar<'a, L: X<&'a Nested<Self>>>();
-   |                   ^^^^^^^^^^^^^^^^^^^
+   = note: ...so that the reference type `&'a Nested<Self>` does not outlive the data it points at
 
 error[E0309]: the parameter type `L` may not live long enough
   --> $DIR/lifetime-doesnt-live-long-enough.rs:32:22
    |
 LL |     fn baz<'a, L, M: X<&'a Nested<L>>>() {
-   |                -     ^^^^^^^^^^^^^^^^
+   |                -     ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<L>` does not outlive the data it points at
    |                |
    |                help: consider adding an explicit lifetime bound...: `L: 'a`
-   |
-note: ...so that the reference type `&'a Nested<L>` does not outlive the data it points at
-  --> $DIR/lifetime-doesnt-live-long-enough.rs:32:22
-   |
-LL |     fn baz<'a, L, M: X<&'a Nested<L>>>() {
-   |                      ^^^^^^^^^^^^^^^^
 
 error[E0309]: the parameter type `K` may not live long enough
   --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33
@@ -59,25 +37,15 @@ error[E0309]: the parameter type `K` may not live long enough
 LL | impl<K> Nested<K> {
    |      - help: consider adding an explicit lifetime bound...: `K: 'a`
 LL |     fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
-   |                                 ^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
-  --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33
-   |
-LL |     fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
-   |                                 ^^^^^^^^^^^^^^^^
+   |                                 ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
 
 error[E0309]: the parameter type `M` may not live long enough
   --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
    |
 LL |     fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
    |                                    ^^^^^^^^^^^^^^^^  -- help: consider adding an explicit lifetime bound...: `M: 'a +`
-   |
-note: ...so that the reference type `&'a Nested<M>` does not outlive the data it points at
-  --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
-   |
-LL |     fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
-   |                                    ^^^^^^^^^^^^^^^^
+   |                                    |
+   |                                    ...so that the reference type `&'a Nested<M>` does not outlive the data it points at
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr
index 1a5a3719fd8..eba00c5a945 100644
--- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.stderr
@@ -5,11 +5,7 @@ LL |     bar::<T::Output>()
    |     ^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<T as MyTrait<'a>>::Output: 'a`...
-note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds
-  --> $DIR/projection-where-clause-env-wrong-bound.rs:15:5
-   |
-LL |     bar::<T::Output>()
-   |     ^^^^^^^^^^^^^^^^
+   = note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr
index d6ade2a603e..34b83859a6b 100644
--- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.stderr
@@ -5,11 +5,7 @@ LL |     bar::<<T as MyTrait<'a>>::Output>()
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<T as MyTrait<'a>>::Output: 'a`...
-note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds
-  --> $DIR/projection-where-clause-env-wrong-lifetime.rs:14:5
-   |
-LL |     bar::<<T as MyTrait<'a>>::Output>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr
index f6252f4ed79..9563c0dff36 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr
@@ -1,11 +1,11 @@
-error[E0621]: explicit lifetime required in the type of `ss`
+error: lifetime may not live long enough
   --> $DIR/object-lifetime-default-from-box-error.rs:18:5
    |
 LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
-   |             --------------- help: add explicit lifetime `'static` to the type of `ss`: `&mut SomeStruct<'static>`
+   |         -- has type `&mut SomeStruct<'1>`
 ...
 LL |     ss.r
-   |     ^^^^ lifetime `'static` required
+   |     ^^^^ returning this value requires that `'1` must outlive `'static`
 
 error[E0507]: cannot move out of `ss.r` which is behind a mutable reference
   --> $DIR/object-lifetime-default-from-box-error.rs:18:5
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.rs b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.rs
index 587aab1edce..708ab1cf382 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.rs
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.rs
@@ -15,7 +15,7 @@ fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
     // `Box<SomeTrait>` defaults to a `'static` bound, so this return
     // is illegal.
 
-    ss.r //~ ERROR explicit lifetime required in the type of `ss` [E0621]
+    ss.r //~ ERROR cannot infer an appropriate lifetime
 }
 
 fn store(ss: &mut SomeStruct, b: Box<dyn SomeTrait>) {
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
index 78e4bdd374d..70a9bf22b8d 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr
@@ -1,11 +1,16 @@
-error[E0621]: explicit lifetime required in the type of `ss`
+error: cannot infer an appropriate lifetime
   --> $DIR/object-lifetime-default-from-box-error.rs:18:5
    |
 LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
-   |             --------------- help: add explicit lifetime `'static` to the type of `ss`: `&mut SomeStruct<'static>`
+   |             --------------- data with this lifetime...
 ...
 LL |     ss.r
-   |     ^^^^ lifetime `'static` required
+   |     ^^^^ ...is captured and required to be `'static` here
+   |
+help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1
+   |
+LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> {
+   |                                                   ^^^^
 
 error[E0621]: explicit lifetime required in the type of `ss`
   --> $DIR/object-lifetime-default-from-box-error.rs:31:12
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
index 767853d8148..bf02ba8eb91 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr
@@ -14,17 +14,17 @@ LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
 LL |     Box::new(v)
    |     ^^^^^^^^^^^ lifetime `'static` required
 
-error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/region-object-lifetime-in-coercion.rs:21:5
+error: lifetime may not live long enough
+  --> $DIR/region-object-lifetime-in-coercion.rs:20:5
    |
 LL | fn c(v: &[u8]) -> Box<dyn Foo> {
-   |         ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+   |         - let's call the lifetime of this reference `'1`
 ...
 LL |     Box::new(v)
-   |     ^^^^^^^^^^^ lifetime `'static` required
+   |     ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/region-object-lifetime-in-coercion.rs:26:5
+  --> $DIR/region-object-lifetime-in-coercion.rs:24:5
    |
 LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
    |      -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.rs b/src/test/ui/regions/region-object-lifetime-in-coercion.rs
index 2dc67599913..d56eaf77b66 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.rs
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.rs
@@ -11,20 +11,17 @@ fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
 }
 
 fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
-    Box::new(v)
-        //~^ ERROR explicit lifetime required in the type of `v` [E0621]
+    Box::new(v) //~ ERROR explicit lifetime required in the type of `v` [E0621]
 }
 
 fn c(v: &[u8]) -> Box<dyn Foo> {
     // same as previous case due to RFC 599
 
-    Box::new(v)
-        //~^ ERROR explicit lifetime required in the type of `v` [E0621]
+    Box::new(v) //~ ERROR cannot infer an appropriate lifetime
 }
 
 fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
-    Box::new(v)
-        //~^ ERROR cannot infer an appropriate lifetime due to conflicting
+    Box::new(v) //~ ERROR cannot infer an appropriate lifetime due to conflicting
 }
 
 fn e<'a:'b,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
index 069b897603c..1462af44cb1 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -14,40 +14,48 @@ LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
 LL |     Box::new(v)
    |     ^^^^^^^^^^^ lifetime `'static` required
 
-error[E0621]: explicit lifetime required in the type of `v`
-  --> $DIR/region-object-lifetime-in-coercion.rs:21:5
+error: cannot infer an appropriate lifetime
+  --> $DIR/region-object-lifetime-in-coercion.rs:20:14
    |
 LL | fn c(v: &[u8]) -> Box<dyn Foo> {
-   |         ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+   |         ----- data with this lifetime...
 ...
 LL |     Box::new(v)
-   |     ^^^^^^^^^^^ lifetime `'static` required
+   |     ---------^-
+   |     |        |
+   |     |        ...and is captured here
+   |     ...is required to be `'static` by this...
+   |
+help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 17:1
+   |
+LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {
+   |                               ^^^^
 
 error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
-  --> $DIR/region-object-lifetime-in-coercion.rs:26:14
+  --> $DIR/region-object-lifetime-in-coercion.rs:24:14
    |
 LL |     Box::new(v)
    |              ^
    |
-note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 25:6...
-  --> $DIR/region-object-lifetime-in-coercion.rs:25:6
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 23:6...
+  --> $DIR/region-object-lifetime-in-coercion.rs:23:6
    |
 LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
    |      ^^
 note: ...so that the expression is assignable
-  --> $DIR/region-object-lifetime-in-coercion.rs:26:14
+  --> $DIR/region-object-lifetime-in-coercion.rs:24:14
    |
 LL |     Box::new(v)
    |              ^
    = note: expected `&[u8]`
               found `&'a [u8]`
-note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 25:9...
-  --> $DIR/region-object-lifetime-in-coercion.rs:25:9
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 23:9...
+  --> $DIR/region-object-lifetime-in-coercion.rs:23:9
    |
 LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
    |         ^^
 note: ...so that the expression is assignable
-  --> $DIR/region-object-lifetime-in-coercion.rs:26:5
+  --> $DIR/region-object-lifetime-in-coercion.rs:24:5
    |
 LL |     Box::new(v)
    |     ^^^^^^^^^^^
diff --git a/src/test/ui/regions/regions-close-associated-type-into-object.stderr b/src/test/ui/regions/regions-close-associated-type-into-object.stderr
index 2401f549a56..9303e0f8e66 100644
--- a/src/test/ui/regions/regions-close-associated-type-into-object.stderr
+++ b/src/test/ui/regions/regions-close-associated-type-into-object.stderr
@@ -5,11 +5,7 @@ LL |     Box::new(item)
    |     ^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'static`...
-note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
-  --> $DIR/regions-close-associated-type-into-object.rs:15:5
-   |
-LL |     Box::new(item)
-   |     ^^^^^^^^^^^^^^
+   = note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
 
 error[E0310]: the associated type `<T as Iter>::Item` may not live long enough
   --> $DIR/regions-close-associated-type-into-object.rs:22:5
@@ -18,11 +14,7 @@ LL |     Box::new(item)
    |     ^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'static`...
-note: ...so that the type `std::boxed::Box<<T as Iter>::Item>` will meet its required lifetime bounds
-  --> $DIR/regions-close-associated-type-into-object.rs:22:5
-   |
-LL |     Box::new(item)
-   |     ^^^^^^^^^^^^^^
+   = note: ...so that the type `std::boxed::Box<<T as Iter>::Item>` will meet its required lifetime bounds
 
 error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
   --> $DIR/regions-close-associated-type-into-object.rs:28:5
@@ -31,11 +23,7 @@ LL |     Box::new(item)
    |     ^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'a`...
-note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
-  --> $DIR/regions-close-associated-type-into-object.rs:28:5
-   |
-LL |     Box::new(item)
-   |     ^^^^^^^^^^^^^^
+   = note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
 
 error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
   --> $DIR/regions-close-associated-type-into-object.rs:35:5
@@ -44,11 +32,7 @@ LL |     Box::new(item)
    |     ^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'a`...
-note: ...so that the type `std::boxed::Box<<T as Iter>::Item>` will meet its required lifetime bounds
-  --> $DIR/regions-close-associated-type-into-object.rs:35:5
-   |
-LL |     Box::new(item)
-   |     ^^^^^^^^^^^^^^
+   = note: ...so that the type `std::boxed::Box<<T as Iter>::Item>` will meet its required lifetime bounds
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/regions/regions-close-object-into-object-5.stderr b/src/test/ui/regions/regions-close-object-into-object-5.stderr
index 2bcdcd1864e..e5a80cbd547 100644
--- a/src/test/ui/regions/regions-close-object-into-object-5.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-5.stderr
@@ -5,13 +5,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
-   |     ^^^^^^^^^^
-   |
-note: ...so that the type `B<'_, T>` will meet its required lifetime bounds
-  --> $DIR/regions-close-object-into-object-5.rs:17:5
-   |
-LL |     box B(&*v) as Box<X>
-   |     ^^^^^^^^^^
+   |     ^^^^^^^^^^ ...so that the type `B<'_, T>` will meet its required lifetime bounds
 
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:9
@@ -20,13 +14,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
-   |         ^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-close-object-into-object-5.rs:17:9
-   |
-LL |     box B(&*v) as Box<X>
-   |         ^
+   |         ^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:9
@@ -35,13 +23,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
-   |         ^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-close-object-into-object-5.rs:17:9
-   |
-LL |     box B(&*v) as Box<X>
-   |         ^^^^^^
+   |         ^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:11
@@ -50,13 +32,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
-   |           ^^^
-   |
-note: ...so that the reference type `&dyn A<T>` does not outlive the data it points at
-  --> $DIR/regions-close-object-into-object-5.rs:17:11
-   |
-LL |     box B(&*v) as Box<X>
-   |           ^^^
+   |           ^^^ ...so that the reference type `&dyn A<T>` does not outlive the data it points at
 
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:11
@@ -65,13 +41,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
-   |           ^^^
-   |
-note: ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
-  --> $DIR/regions-close-object-into-object-5.rs:17:11
-   |
-LL |     box B(&*v) as Box<X>
-   |           ^^^
+   |           ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
 
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:11
@@ -80,13 +50,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
    |          - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
-   |           ^^^
-   |
-note: ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
-  --> $DIR/regions-close-object-into-object-5.rs:17:11
-   |
-LL |     box B(&*v) as Box<X>
-   |           ^^^
+   |           ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr b/src/test/ui/regions/regions-close-over-type-parameter-1.stderr
index a7509cb608c..50274b066df 100644
--- a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr
+++ b/src/test/ui/regions/regions-close-over-type-parameter-1.stderr
@@ -4,13 +4,7 @@ error[E0310]: the parameter type `A` may not live long enough
 LL | fn make_object1<A: SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
    |                 -- help: consider adding an explicit lifetime bound...: `A: 'static +`
 LL |     box v as Box<dyn SomeTrait + 'static>
-   |     ^^^^^
-   |
-note: ...so that the type `A` will meet its required lifetime bounds
-  --> $DIR/regions-close-over-type-parameter-1.rs:12:5
-   |
-LL |     box v as Box<dyn SomeTrait + 'static>
-   |     ^^^^^
+   |     ^^^^^ ...so that the type `A` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `A` may not live long enough
   --> $DIR/regions-close-over-type-parameter-1.rs:21:5
@@ -18,13 +12,7 @@ error[E0309]: the parameter type `A` may not live long enough
 LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> {
    |                         -- help: consider adding an explicit lifetime bound...: `A: 'b +`
 LL |     box v as Box<dyn SomeTrait + 'b>
-   |     ^^^^^
-   |
-note: ...so that the type `A` will meet its required lifetime bounds
-  --> $DIR/regions-close-over-type-parameter-1.rs:21:5
-   |
-LL |     box v as Box<dyn SomeTrait + 'b>
-   |     ^^^^^
+   |     ^^^^^ ...so that the type `A` will meet its required lifetime bounds
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/regions/regions-close-param-into-object.stderr b/src/test/ui/regions/regions-close-param-into-object.stderr
index 3b1a89d9ced..705d21078ec 100644
--- a/src/test/ui/regions/regions-close-param-into-object.stderr
+++ b/src/test/ui/regions/regions-close-param-into-object.stderr
@@ -5,13 +5,7 @@ LL | fn p1<T>(v: T) -> Box<dyn X + 'static>
    |       - help: consider adding an explicit lifetime bound...: `T: 'static`
 ...
 LL |     Box::new(v)
-   |     ^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-close-param-into-object.rs:6:5
-   |
-LL |     Box::new(v)
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-param-into-object.rs:12:5
@@ -20,13 +14,7 @@ LL | fn p2<T>(v: Box<T>) -> Box<dyn X + 'static>
    |       - help: consider adding an explicit lifetime bound...: `T: 'static`
 ...
 LL |     Box::new(v)
-   |     ^^^^^^^^^^^
-   |
-note: ...so that the type `std::boxed::Box<T>` will meet its required lifetime bounds
-  --> $DIR/regions-close-param-into-object.rs:12:5
-   |
-LL |     Box::new(v)
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ ...so that the type `std::boxed::Box<T>` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-param-into-object.rs:18:5
@@ -35,13 +23,7 @@ LL | fn p3<'a,T>(v: T) -> Box<dyn X + 'a>
    |          - help: consider adding an explicit lifetime bound...: `T: 'a`
 ...
 LL |     Box::new(v)
-   |     ^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-close-param-into-object.rs:18:5
-   |
-LL |     Box::new(v)
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-param-into-object.rs:24:5
@@ -50,13 +32,7 @@ LL | fn p4<'a,T>(v: Box<T>) -> Box<dyn X + 'a>
    |          - help: consider adding an explicit lifetime bound...: `T: 'a`
 ...
 LL |     Box::new(v)
-   |     ^^^^^^^^^^^
-   |
-note: ...so that the type `std::boxed::Box<T>` will meet its required lifetime bounds
-  --> $DIR/regions-close-param-into-object.rs:24:5
-   |
-LL |     Box::new(v)
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ ...so that the type `std::boxed::Box<T>` will meet its required lifetime bounds
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/regions/regions-enum-not-wf.stderr b/src/test/ui/regions/regions-enum-not-wf.stderr
index 297fcb088d2..e32a36f72cd 100644
--- a/src/test/ui/regions/regions-enum-not-wf.stderr
+++ b/src/test/ui/regions/regions-enum-not-wf.stderr
@@ -4,13 +4,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | enum Ref1<'a, T> {
    |               - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     Ref1Variant1(RequireOutlives<'a, T>)
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-enum-not-wf.rs:18:18
-   |
-LL |     Ref1Variant1(RequireOutlives<'a, T>)
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/regions-enum-not-wf.rs:23:25
@@ -19,13 +13,7 @@ LL | enum Ref2<'a, T> {
    |               - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     Ref2Variant1,
 LL |     Ref2Variant2(isize, RequireOutlives<'a, T>),
-   |                         ^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-enum-not-wf.rs:23:25
-   |
-LL |     Ref2Variant2(isize, RequireOutlives<'a, T>),
-   |                         ^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/regions-enum-not-wf.rs:35:1
@@ -37,16 +25,7 @@ LL |   enum RefDouble<'a, 'b, T> {
 LL | |     RefDoubleVariant1(&'a RequireOutlives<'b, T>)
 LL | |
 LL | | }
-   | |_^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-enum-not-wf.rs:35:1
-   |
-LL | / enum RefDouble<'a, 'b, T> {
-LL | |     RefDoubleVariant1(&'a RequireOutlives<'b, T>)
-LL | |
-LL | | }
-   | |_^
+   | |_^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/regions-enum-not-wf.rs:36:23
@@ -54,13 +33,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | enum RefDouble<'a, 'b, T> {
    |                        - help: consider adding an explicit lifetime bound...: `T: 'b`
 LL |     RefDoubleVariant1(&'a RequireOutlives<'b, T>)
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-enum-not-wf.rs:36:23
-   |
-LL |     RefDoubleVariant1(&'a RequireOutlives<'b, T>)
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
index 2f1a4cea8e9..ea59ea11a14 100644
--- a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr
@@ -5,13 +5,7 @@ LL | fn func<'x, T:Trait1<'x>>(t: &'x T::Foo)
    |             -- help: consider adding an explicit lifetime bound...: `T: 'x +`
 LL | {
 LL |     wf::<&'x T>();
-   |          ^^^^^
-   |
-note: ...so that the reference type `&'x T` does not outlive the data it points at
-  --> $DIR/regions-implied-bounds-projection-gap-1.rs:16:10
-   |
-LL |     wf::<&'x T>();
-   |          ^^^^^
+   |          ^^^^^ ...so that the reference type `&'x T` does not outlive the data it points at
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr b/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr
index bcdadd7a73d..4ca5ac291d5 100644
--- a/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr
+++ b/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr
@@ -5,11 +5,7 @@ LL |         check_bound(x, self)
    |         ^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `Self: 'a`...
-note: ...so that the type `Self` will meet its required lifetime bounds
-  --> $DIR/regions-infer-bound-from-trait-self.rs:46:9
-   |
-LL |         check_bound(x, self)
-   |         ^^^^^^^^^^^
+   = note: ...so that the type `Self` will meet its required lifetime bounds
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/regions/regions-infer-bound-from-trait.stderr b/src/test/ui/regions/regions-infer-bound-from-trait.stderr
index a5a0ff52fac..196ee8ca7c0 100644
--- a/src/test/ui/regions/regions-infer-bound-from-trait.stderr
+++ b/src/test/ui/regions/regions-infer-bound-from-trait.stderr
@@ -4,13 +4,7 @@ error[E0309]: the parameter type `A` may not live long enough
 LL | fn bar1<'a,A>(x: Inv<'a>, a: A) {
    |            - help: consider adding an explicit lifetime bound...: `A: 'a`
 LL |     check_bound(x, a)
-   |     ^^^^^^^^^^^
-   |
-note: ...so that the type `A` will meet its required lifetime bounds
-  --> $DIR/regions-infer-bound-from-trait.rs:33:5
-   |
-LL |     check_bound(x, a)
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `A` may not live long enough
   --> $DIR/regions-infer-bound-from-trait.rs:37:5
@@ -18,13 +12,7 @@ error[E0309]: the parameter type `A` may not live long enough
 LL | fn bar2<'a,'b,A:Is<'b>>(x: Inv<'a>, y: Inv<'b>, a: A) {
    |               -- help: consider adding an explicit lifetime bound...: `A: 'a +`
 LL |     check_bound(x, a)
-   |     ^^^^^^^^^^^
-   |
-note: ...so that the type `A` will meet its required lifetime bounds
-  --> $DIR/regions-infer-bound-from-trait.rs:37:5
-   |
-LL |     check_bound(x, a)
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
index c3cfc5a4d97..2bb51731583 100644
--- a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
@@ -4,13 +4,7 @@ error[E0310]: the parameter type `U` may not live long enough
 LL | struct Foo<U> {
    |            - help: consider adding an explicit lifetime bound...: `U: 'static`
 LL |     bar: Bar<U>
-   |     ^^^^^^^^^^^
-   |
-note: ...so that the type `U` will meet its required lifetime bounds
-  --> $DIR/dont-infer-static.rs:8:5
-   |
-LL |     bar: Bar<U>
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
index 297fcb088d2..e32a36f72cd 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
@@ -4,13 +4,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | enum Ref1<'a, T> {
    |               - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     Ref1Variant1(RequireOutlives<'a, T>)
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-enum-not-wf.rs:18:18
-   |
-LL |     Ref1Variant1(RequireOutlives<'a, T>)
-   |                  ^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/regions-enum-not-wf.rs:23:25
@@ -19,13 +13,7 @@ LL | enum Ref2<'a, T> {
    |               - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     Ref2Variant1,
 LL |     Ref2Variant2(isize, RequireOutlives<'a, T>),
-   |                         ^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-enum-not-wf.rs:23:25
-   |
-LL |     Ref2Variant2(isize, RequireOutlives<'a, T>),
-   |                         ^^^^^^^^^^^^^^^^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/regions-enum-not-wf.rs:35:1
@@ -37,16 +25,7 @@ LL |   enum RefDouble<'a, 'b, T> {
 LL | |     RefDoubleVariant1(&'a RequireOutlives<'b, T>)
 LL | |
 LL | | }
-   | |_^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-enum-not-wf.rs:35:1
-   |
-LL | / enum RefDouble<'a, 'b, T> {
-LL | |     RefDoubleVariant1(&'a RequireOutlives<'b, T>)
-LL | |
-LL | | }
-   | |_^
+   | |_^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/regions-enum-not-wf.rs:36:23
@@ -54,13 +33,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | enum RefDouble<'a, 'b, T> {
    |                        - help: consider adding an explicit lifetime bound...: `T: 'b`
 LL |     RefDoubleVariant1(&'a RequireOutlives<'b, T>)
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-enum-not-wf.rs:36:23
-   |
-LL |     RefDoubleVariant1(&'a RequireOutlives<'b, T>)
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
index f6658891fa6..44812a51778 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
@@ -4,13 +4,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | impl<'a, T> Trait<'a, T> for usize {
    |          - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     type Out = &'a T;
-   |     ^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'a T` does not outlive the data it points at
-  --> $DIR/regions-struct-not-wf.rs:13:5
-   |
-LL |     type Out = &'a T;
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/regions-struct-not-wf.rs:21:5
@@ -18,13 +12,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | impl<'a, T> Trait<'a, T> for u32 {
    |          - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     type Out = RefOk<'a, T>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-struct-not-wf.rs:21:5
-   |
-LL |     type Out = RefOk<'a, T>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 
 error[E0491]: in type `&'a &'b T`, reference has a longer lifetime than the data it references
   --> $DIR/regions-struct-not-wf.rs:25:5
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
index 91075ffbdb6..1aeabce5e8a 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
@@ -2,15 +2,10 @@ error: cannot infer an appropriate lifetime
   --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
-   |                ^^^^                 ---------- this return type evaluates to the `'static` lifetime...
-   |                |
-   |                ...but this borrow...
-   |
-note: ...can't outlive the lifetime `'_` as defined on the method body at 8:26
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:26
-   |
-LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
-   |                          ^
+   |                ^^^^  ----------     ---------- ...and required to be `'static` by this
+   |                |     |
+   |                |     data with this lifetime...
+   |                ...is captured here...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
index 47ab6fff838..04c475be787 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr
@@ -2,19 +2,15 @@ error: cannot infer an appropriate lifetime
   --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
-   |                               ----------   ^^^^ ...but this borrow...
-   |                               |
-   |                               this return type evaluates to the `'static` lifetime...
+   |                ----------     ----------   ^^^^ ...and is captured here
+   |                |              |
+   |                |              ...is required to be `'static` by this...
+   |                data with this lifetime...
    |
-note: ...can't outlive the anonymous lifetime #1 defined on the method body at 6:5
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:5
-   |
-LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
-   |                               ^^^^^^^^^^^^^^^
+   |                                          ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr
new file mode 100644
index 00000000000..2072b00f7b2
--- /dev/null
+++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr
@@ -0,0 +1,115 @@
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/missing-lifetimes-in-signature.rs:37:11
+   |
+LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |        -  ^^ undeclared lifetime
+   |        |
+   |        help: consider introducing lifetime `'a` here: `'a,`
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:15:37
+   |
+LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
+   |                          -          ^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+   |                          |
+   |                          let's call the lifetime of this reference `'1`
+   |
+help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
+   |
+LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |                                     ^^^^^^^^^^^^^^^^^^
+
+error[E0311]: the parameter type `G` may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:25:37
+   |
+LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |                                     ^^^^^^^^^^^^^^^^^^
+   |
+note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 25:1...
+  --> $DIR/missing-lifetimes-in-signature.rs:25:1
+   |
+LL | / fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+LL | |
+LL | | where
+LL | |     G: Get<T>
+...  |
+LL | |     }
+LL | | }
+   | |_^
+
+error[E0311]: the parameter type `G` may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:47:45
+   |
+LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |                                             ^^^^^^^^^^^^^^^^^^
+   |
+note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 47:1...
+  --> $DIR/missing-lifetimes-in-signature.rs:47:1
+   |
+LL | / fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+LL | |
+LL | | where
+LL | |     G: Get<T>
+...  |
+LL | |     }
+LL | | }
+   | |_^
+
+error[E0311]: the parameter type `G` may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:59:58
+   |
+LL |     fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
+   |                                                          ^^^^^^^^^^^^^^^^^^
+   |
+note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the method body at 59:5...
+  --> $DIR/missing-lifetimes-in-signature.rs:59:5
+   |
+LL | /     fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
+LL | |
+LL | |         move || {
+LL | |             *dest = g.get();
+LL | |         }
+LL | |     }
+   | |_____^
+
+error[E0311]: the parameter type `G` may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:68:45
+   |
+LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 68:1...
+  --> $DIR/missing-lifetimes-in-signature.rs:68:1
+   |
+LL | / fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+LL | |
+LL | | where
+LL | |     G: Get<T>
+...  |
+LL | |     }
+LL | | }
+   | |_^
+
+error[E0621]: explicit lifetime required in the type of `dest`
+  --> $DIR/missing-lifetimes-in-signature.rs:73:5
+   |
+LL |   fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+   |                                    ------ help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
+...
+LL | /     move || {
+LL | |         *dest = g.get();
+LL | |     }
+   | |_____^ lifetime `'a` required
+
+error[E0309]: the parameter type `G` may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:79:44
+   |
+LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
+   |                                            ^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding an explicit lifetime bound `G: 'a`...
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0261, E0309, E0621.
+For more information about an error, try `rustc --explain E0261`.
diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
new file mode 100644
index 00000000000..d3853445dfd
--- /dev/null
+++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
@@ -0,0 +1,110 @@
+pub trait Get<T> {
+    fn get(self) -> T;
+}
+
+struct Foo {
+    x: usize,
+}
+
+impl Get<usize> for Foo {
+    fn get(self) -> usize {
+        self.x
+    }
+}
+
+fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
+where
+    G: Get<T>
+{
+    move || { //~ ERROR cannot infer an appropriate lifetime
+        *dest = g.get();
+    }
+}
+
+// After applying suggestion for `foo`:
+fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+//~^ ERROR the parameter type `G` may not live long enough
+where
+    G: Get<T>
+{
+    move || {
+        *dest = g.get();
+    }
+}
+
+
+// After applying suggestion for `bar`:
+fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ //~ ERROR undeclared lifetime
+where
+    G: Get<T>
+{
+    move || {
+        *dest = g.get();
+    }
+}
+
+// After applying suggestion for `baz`:
+fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+//~^ ERROR the parameter type `G` may not live long enough
+where
+    G: Get<T>
+{
+    move || {
+        *dest = g.get();
+    }
+}
+
+// Same as above, but show that we pay attention to lifetime names from parent item
+impl<'a> Foo {
+    fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
+        //~^ ERROR the parameter type `G` may not live long enough
+        move || {
+            *dest = g.get();
+        }
+    }
+}
+
+// After applying suggestion for `qux`:
+fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+//~^ ERROR explicit lifetime required in the type of `dest`
+where
+    G: Get<T>
+{
+    move || {
+        *dest = g.get();
+    }
+}
+
+// Potential incorrect attempt:
+fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
+//~^ ERROR the parameter type `G` may not live long enough
+where
+    G: Get<T>
+{
+    move || {
+        *dest = g.get();
+    }
+}
+
+
+// We need to tie the lifetime of `G` with the lifetime of `&mut T` and the returned closure:
+fn ok<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
+where
+    G: Get<T>
+{
+    move || {
+        *dest = g.get();
+    }
+}
+
+// This also works. The `'_` isn't necessary but it's where we arrive to following the suggestions:
+fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
+where
+    G: Get<T>
+{
+    move || {
+        *dest = g.get();
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
new file mode 100644
index 00000000000..5cf170d566c
--- /dev/null
+++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -0,0 +1,126 @@
+error[E0261]: use of undeclared lifetime name `'a`
+  --> $DIR/missing-lifetimes-in-signature.rs:37:11
+   |
+LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |        -  ^^ undeclared lifetime
+   |        |
+   |        help: consider introducing lifetime `'a` here: `'a,`
+
+error: cannot infer an appropriate lifetime
+  --> $DIR/missing-lifetimes-in-signature.rs:19:5
+   |
+LL |   fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
+   |                            ------     ------------- ...is required to be `'static` by this...
+   |                            |
+   |                            data with this lifetime...
+...
+LL | /     move || {
+LL | |         *dest = g.get();
+LL | |     }
+   | |_____^ ...and is captured here
+   |
+help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 15:1
+   |
+LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |                                                   ^^^^
+
+error[E0311]: the parameter type `G` may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:25:37
+   |
+LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |                                     ^^^^^^^^^^^^^^^^^^
+   |
+note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 25:1...
+  --> $DIR/missing-lifetimes-in-signature.rs:25:1
+   |
+LL | / fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+LL | |
+LL | | where
+LL | |     G: Get<T>
+...  |
+LL | |     }
+LL | | }
+   | |_^
+note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:30:5: 32:6 g:G, dest:&mut T]` will meet its required lifetime bounds
+  --> $DIR/missing-lifetimes-in-signature.rs:25:37
+   |
+LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |                                     ^^^^^^^^^^^^^^^^^^
+help: consider introducing an explicit lifetime bound
+   |
+LL | fn bar<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+   |        ^^^^^                                                   ^^^^
+
+error[E0311]: the parameter type `G` may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:47:45
+   |
+LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |                                             ^^^^^^^^^^^^^^^^^^
+   |
+note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 47:1...
+  --> $DIR/missing-lifetimes-in-signature.rs:47:1
+   |
+LL | / fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+LL | |
+LL | | where
+LL | |     G: Get<T>
+...  |
+LL | |     }
+LL | | }
+   | |_^
+note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:52:5: 54:6 g:G, dest:&mut T]` will meet its required lifetime bounds
+  --> $DIR/missing-lifetimes-in-signature.rs:47:45
+   |
+LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+   |                                             ^^^^^^^^^^^^^^^^^^
+help: consider introducing an explicit lifetime bound
+   |
+LL | fn qux<'b, 'a, G: 'b + 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'b
+   |        ^^^     ^^^^^^^                                                  ^^^^
+
+error[E0311]: the parameter type `G` may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:59:58
+   |
+LL |     fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
+   |                                                          ^^^^^^^^^^^^^^^^^^
+   |
+note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the method body at 59:5...
+  --> $DIR/missing-lifetimes-in-signature.rs:59:5
+   |
+LL | /     fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
+LL | |
+LL | |         move || {
+LL | |             *dest = g.get();
+LL | |         }
+LL | |     }
+   | |_____^
+note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:61:9: 63:10 g:G, dest:&mut T]` will meet its required lifetime bounds
+  --> $DIR/missing-lifetimes-in-signature.rs:59:58
+   |
+LL |     fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
+   |                                                          ^^^^^^^^^^^^^^^^^^
+help: consider introducing an explicit lifetime bound
+   |
+LL |     fn qux<'c, 'b, G: 'c + Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'c {
+   |            ^^^     ^^^^^^^                                                           ^^^^
+
+error[E0621]: explicit lifetime required in the type of `dest`
+  --> $DIR/missing-lifetimes-in-signature.rs:68:45
+   |
+LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+   |                                  ------     ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
+   |                                  |
+   |                                  help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
+
+error[E0309]: the parameter type `G` may not live long enough
+  --> $DIR/missing-lifetimes-in-signature.rs:79:44
+   |
+LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
+   |            -                               ^^^^^^^^^^^^^^^^^^ ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:84:5: 86:6 g:G, dest:&mut T]` will meet its required lifetime bounds
+   |            |
+   |            help: consider adding an explicit lifetime bound...: `G: 'a`
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0261, E0309, E0621.
+For more information about an error, try `rustc --explain E0261`.
diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
index b6e6c0bbf32..643dac25724 100644
--- a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
+++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
@@ -5,13 +5,7 @@ LL | fn foo(d: impl Debug) {
    |           ---------- help: consider adding an explicit lifetime bound...: `impl Debug + 'static`
 LL |
 LL |     bar(d);
-   |     ^^^
-   |
-note: ...so that the type `impl Debug` will meet its required lifetime bounds
-  --> $DIR/suggest-impl-trait-lifetime.rs:7:5
-   |
-LL |     bar(d);
-   |     ^^^
+   |     ^^^ ...so that the type `impl Debug` will meet its required lifetime bounds
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
index 22e2391f838..e2540e424cb 100644
--- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
+++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr
@@ -22,16 +22,10 @@ error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/generic_type_does_not_live_long_enough.rs:9:1
    |
 LL | type WrongGeneric<T> = impl 'static;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
 ...
 LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                  - help: consider adding an explicit lifetime bound...: `T: 'static`
-   |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/generic_type_does_not_live_long_enough.rs:9:1
-   |
-LL | type WrongGeneric<T> = impl 'static;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
index e3c9d50dfe5..3577dd59289 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -1,31 +1,16 @@
-error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
+error: cannot infer an appropriate lifetime
   --> $DIR/dyn-trait-underscore.rs:8:20
    |
+LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
+   |                ---- data with this lifetime...
+LL |     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
 LL |     Box::new(items.iter())
-   |                    ^^^^
+   |     ---------------^^^^--- ...is captured and required to be `'static` here
    |
-note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 6:1...
-  --> $DIR/dyn-trait-underscore.rs:6:1
+help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1
    |
-LL | / fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
-LL | |     //                      ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
-LL | |     Box::new(items.iter())
-LL | | }
-   | |_^
-note: ...so that reference does not outlive borrowed content
-  --> $DIR/dyn-trait-underscore.rs:8:14
-   |
-LL |     Box::new(items.iter())
-   |              ^^^^^
-   = note: but, the lifetime must be valid for the static lifetime...
-note: ...so that the expression is assignable
-  --> $DIR/dyn-trait-underscore.rs:8:5
-   |
-LL |     Box::new(items.iter())
-   |     ^^^^^^^^^^^^^^^^^^^^^^
-   = note: expected `std::boxed::Box<(dyn std::iter::Iterator<Item = &T> + 'static)>`
-              found `std::boxed::Box<dyn std::iter::Iterator<Item = &T>>`
+LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
+   |                                                   ^^^^
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/wf/wf-impl-associated-type-region.stderr b/src/test/ui/wf/wf-impl-associated-type-region.stderr
index 9942c80effe..f3b32ad3f7e 100644
--- a/src/test/ui/wf/wf-impl-associated-type-region.stderr
+++ b/src/test/ui/wf/wf-impl-associated-type-region.stderr
@@ -4,13 +4,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | impl<'a, T> Foo<'a> for T {
    |          - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     type Bar = &'a T;
-   |     ^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'a T` does not outlive the data it points at
-  --> $DIR/wf-impl-associated-type-region.rs:10:5
-   |
-LL |     type Bar = &'a T;
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-type-static.stderr b/src/test/ui/wf/wf-in-fn-type-static.stderr
index 7dc8f5a9661..a79c4462477 100644
--- a/src/test/ui/wf/wf-in-fn-type-static.stderr
+++ b/src/test/ui/wf/wf-in-fn-type-static.stderr
@@ -5,13 +5,7 @@ LL | struct Foo<T> {
    |            - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // needs T: 'static
 LL |     x: fn() -> &'static T
-   |     ^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'static T` does not outlive the data it points at
-  --> $DIR/wf-in-fn-type-static.rs:13:5
-   |
-LL |     x: fn() -> &'static T
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
 
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/wf-in-fn-type-static.rs:18:5
@@ -20,13 +14,7 @@ LL | struct Bar<T> {
    |            - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // needs T: Copy
 LL |     x: fn(&'static T)
-   |     ^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'static T` does not outlive the data it points at
-  --> $DIR/wf-in-fn-type-static.rs:18:5
-   |
-LL |     x: fn(&'static T)
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/wf/wf-in-obj-type-static.stderr b/src/test/ui/wf/wf-in-obj-type-static.stderr
index 32c3198d55b..c0057f3c829 100644
--- a/src/test/ui/wf/wf-in-obj-type-static.stderr
+++ b/src/test/ui/wf/wf-in-obj-type-static.stderr
@@ -5,13 +5,7 @@ LL | struct Foo<T> {
    |            - help: consider adding an explicit lifetime bound...: `T: 'static`
 LL |     // needs T: 'static
 LL |     x: dyn Object<&'static T>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'static T` does not outlive the data it points at
-  --> $DIR/wf-in-obj-type-static.rs:14:5
-   |
-LL |     x: dyn Object<&'static T>
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
index 52786fb3bca..4c25ab95939 100644
--- a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
+++ b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
@@ -4,13 +4,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | impl<'a, T> Trait<'a, T> for usize {
    |          - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     type Out = &'a fn(T);
-   |     ^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'a fn(T)` does not outlive the data it points at
-  --> $DIR/wf-outlives-ty-in-fn-or-trait.rs:9:5
-   |
-LL |     type Out = &'a fn(T);
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'a fn(T)` does not outlive the data it points at
 
 error[E0309]: the parameter type `T` may not live long enough
   --> $DIR/wf-outlives-ty-in-fn-or-trait.rs:19:5
@@ -18,13 +12,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL | impl<'a, T> Trait<'a, T> for u32 {
    |          - help: consider adding an explicit lifetime bound...: `T: 'a`
 LL |     type Out = &'a dyn Baz<T>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...so that the reference type `&'a (dyn Baz<T> + 'a)` does not outlive the data it points at
-  --> $DIR/wf-outlives-ty-in-fn-or-trait.rs:19:5
-   |
-LL |     type Out = &'a dyn Baz<T>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'a (dyn Baz<T> + 'a)` does not outlive the data it points at
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/wf/wf-trait-associated-type-region.stderr b/src/test/ui/wf/wf-trait-associated-type-region.stderr
index 9bbfad90cdb..ae681ba6c9b 100644
--- a/src/test/ui/wf/wf-trait-associated-type-region.stderr
+++ b/src/test/ui/wf/wf-trait-associated-type-region.stderr
@@ -5,11 +5,7 @@ LL |     type Type2 = &'a Self::Type1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding an explicit lifetime bound `<Self as SomeTrait<'a>>::Type1: 'a`...
-note: ...so that the reference type `&'a <Self as SomeTrait<'a>>::Type1` does not outlive the data it points at
-  --> $DIR/wf-trait-associated-type-region.rs:9:5
-   |
-LL |     type Type2 = &'a Self::Type1;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...so that the reference type `&'a <Self as SomeTrait<'a>>::Type1` does not outlive the data it points at
 
 error: aborting due to previous error