about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs10
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs27
-rw-r--r--compiler/rustc_trait_selection/src/opaque_types.rs106
-rw-r--r--compiler/rustc_typeck/src/check/regionck.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr32
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs9
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr41
-rw-r--r--src/test/ui/impl-trait/hidden-lifetimes.nll.stderr29
-rw-r--r--src/test/ui/impl-trait/hidden-lifetimes.stderr2
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr49
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs11
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr111
-rw-r--r--src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr47
-rw-r--r--src/test/ui/impl-trait/static-return-lifetime-infered.rs12
-rw-r--r--src/test/ui/impl-trait/static-return-lifetime-infered.stderr106
-rw-r--r--src/test/ui/nll/issue-73159-rpit-static.rs3
-rw-r--r--src/test/ui/nll/issue-73159-rpit-static.stderr7
-rw-r--r--src/test/ui/nll/ty-outlives/impl-trait-captures.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/impl-trait-captures.stderr14
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr9
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs3
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr30
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr9
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs3
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.stderr16
-rw-r--r--src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr16
-rw-r--r--src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs2
-rw-r--r--src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr16
-rw-r--r--src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr26
29 files changed, 419 insertions, 331 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 21c26af8178..22bb3a29425 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -689,6 +689,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // them down.
         let mut choice_regions: Vec<ty::RegionVid> = choice_regions.to_vec();
 
+        // Convert to the SCC representative: sometimes we have inference
+        // variables in the member constraint that wind up equated with
+        // universal regions. The scc representative is the minimal numbered
+        // one from the corresponding scc so it will be the universal region
+        // if one exists.
+        for c_r in &mut choice_regions {
+            let scc = self.constraint_sccs.scc(*c_r);
+            *c_r = self.scc_representatives[scc];
+        }
+
         // The 'member region' in a member constraint is part of the
         // hidden type, which must be in the root universe. Therefore,
         // it cannot have any placeholders in its value.
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 7bf119863fd..7e69e710d68 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -36,7 +36,7 @@ use rustc_span::def_id::CRATE_DEF_ID;
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::VariantIdx;
 use rustc_trait_selection::infer::InferCtxtExt as _;
-use rustc_trait_selection::opaque_types::{GenerateMemberConstraints, InferCtxtExt};
+use rustc_trait_selection::opaque_types::InferCtxtExt;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::type_op;
 use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
@@ -185,7 +185,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
         &region_bound_pairs,
         implicit_region_bound,
         &mut borrowck_context,
-        &universal_region_relations,
         |mut cx| {
             cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
             liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
@@ -253,15 +252,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
 }
 
 #[instrument(
-    skip(
-        infcx,
-        body,
-        promoted,
-        region_bound_pairs,
-        borrowck_context,
-        universal_region_relations,
-        extra
-    ),
+    skip(infcx, body, promoted, region_bound_pairs, borrowck_context, extra),
     level = "debug"
 )]
 fn type_check_internal<'a, 'tcx, R>(
@@ -272,7 +263,6 @@ fn type_check_internal<'a, 'tcx, R>(
     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
     implicit_region_bound: ty::Region<'tcx>,
     borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
-    universal_region_relations: &'a UniversalRegionRelations<'tcx>,
     extra: impl FnOnce(TypeChecker<'a, 'tcx>) -> R,
 ) -> R {
     let mut checker = TypeChecker::new(
@@ -282,7 +272,6 @@ fn type_check_internal<'a, 'tcx, R>(
         region_bound_pairs,
         implicit_region_bound,
         borrowck_context,
-        universal_region_relations,
     );
     let errors_reported = {
         let mut verifier = TypeVerifier::new(&mut checker, body, promoted);
@@ -901,7 +890,6 @@ struct TypeChecker<'a, 'tcx> {
     implicit_region_bound: ty::Region<'tcx>,
     reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
     borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
-    universal_region_relations: &'a UniversalRegionRelations<'tcx>,
 }
 
 struct BorrowCheckContext<'a, 'tcx> {
@@ -1050,7 +1038,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         region_bound_pairs: &'a RegionBoundPairs<'tcx>,
         implicit_region_bound: ty::Region<'tcx>,
         borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
-        universal_region_relations: &'a UniversalRegionRelations<'tcx>,
     ) -> Self {
         let mut checker = Self {
             infcx,
@@ -1062,7 +1049,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             implicit_region_bound,
             borrowck_context,
             reported_errors: Default::default(),
-            universal_region_relations,
         };
         checker.check_user_type_annotations();
         checker
@@ -1322,8 +1308,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             ),
         )?;
 
-        let universal_region_relations = self.universal_region_relations;
-
         // Finally, if we instantiated the anon types successfully, we
         // have to solve any bounds (e.g., `-> impl Iterator` needs to
         // prove that `T: Iterator` where `T` is the type we
@@ -1335,12 +1319,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 ConstraintCategory::OpaqueType,
                 CustomTypeOp::new(
                     |infcx| {
-                        infcx.constrain_opaque_type(
-                            opaque_type_key,
-                            &opaque_decl,
-                            GenerateMemberConstraints::IfNoStaticBound,
-                            universal_region_relations,
-                        );
+                        infcx.constrain_opaque_type(opaque_type_key, &opaque_decl);
                         Ok(InferOk { value: (), obligations: vec![] })
                     },
                     || "opaque_type_map".to_string(),
diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs
index c2205462680..db217cc6137 100644
--- a/compiler/rustc_trait_selection/src/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/opaque_types.rs
@@ -4,7 +4,6 @@ use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
-use rustc_infer::infer::free_regions::FreeRegionRelations;
 use rustc_infer::infer::opaque_types::OpaqueTypeDecl;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{self, InferCtxt, InferOk};
@@ -37,14 +36,12 @@ pub trait InferCtxtExt<'tcx> {
         value_span: Span,
     ) -> InferOk<'tcx, T>;
 
-    fn constrain_opaque_types<FRR: FreeRegionRelations<'tcx>>(&self, free_region_relations: &FRR);
+    fn constrain_opaque_types(&self);
 
-    fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
+    fn constrain_opaque_type(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
         opaque_defn: &OpaqueTypeDecl<'tcx>,
-        mode: GenerateMemberConstraints,
-        free_region_relations: &FRR,
     );
 
     /*private*/
@@ -270,26 +267,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     /// - `opaque_types` -- the map produced by `instantiate_opaque_types`
     /// - `free_region_relations` -- something that can be used to relate
     ///   the free regions (`'a`) that appear in the impl trait.
-    fn constrain_opaque_types<FRR: FreeRegionRelations<'tcx>>(&self, free_region_relations: &FRR) {
+    fn constrain_opaque_types(&self) {
         let opaque_types = self.inner.borrow().opaque_types.clone();
         for (opaque_type_key, opaque_defn) in opaque_types {
-            self.constrain_opaque_type(
-                opaque_type_key,
-                &opaque_defn,
-                GenerateMemberConstraints::WhenRequired,
-                free_region_relations,
-            );
+            self.constrain_opaque_type(opaque_type_key, &opaque_defn);
         }
     }
 
     /// See `constrain_opaque_types` for documentation.
-    #[instrument(level = "debug", skip(self, free_region_relations))]
-    fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
+    #[instrument(level = "debug", skip(self))]
+    fn constrain_opaque_type(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
         opaque_defn: &OpaqueTypeDecl<'tcx>,
-        mode: GenerateMemberConstraints,
-        free_region_relations: &FRR,
     ) {
         let def_id = opaque_type_key.def_id;
 
@@ -347,6 +337,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         debug!("{:#?}", bounds);
         let opaque_type = tcx.mk_opaque(def_id, opaque_type_key.substs);
 
+        // (A) The regions that appear in the hidden type must be equal to
+        // one of the regions in scope for the opaque type.
+        self.generate_member_constraint(
+            concrete_ty,
+            opaque_defn,
+            opaque_type_key,
+            first_own_region,
+        );
+
+        // (B) We can also generate outlives bounds that must be enforced.
         let required_region_bounds = required_region_bounds(tcx, opaque_type, bounds);
         if !required_region_bounds.is_empty() {
             for required_region in required_region_bounds {
@@ -355,81 +355,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     op: |r| self.sub_regions(infer::CallReturn(span), required_region, r),
                 });
             }
-            if let GenerateMemberConstraints::IfNoStaticBound = mode {
-                self.generate_member_constraint(
-                    concrete_ty,
-                    opaque_defn,
-                    opaque_type_key,
-                    first_own_region,
-                );
-            }
-            return;
         }
-
-        // There were no `required_region_bounds`,
-        // so we have to search for a `least_region`.
-        // Go through all the regions used as arguments to the
-        // opaque type. These are the parameters to the opaque
-        // type; so in our example above, `substs` would contain
-        // `['a]` for the first impl trait and `'b` for the
-        // second.
-        let mut least_region = None;
-
-        for subst_arg in &opaque_type_key.substs[first_own_region..] {
-            let subst_region = match subst_arg.unpack() {
-                GenericArgKind::Lifetime(r) => r,
-                GenericArgKind::Type(_) | GenericArgKind::Const(_) => continue,
-            };
-
-            // Compute the least upper bound of it with the other regions.
-            debug!(?least_region);
-            debug!(?subst_region);
-            match least_region {
-                None => least_region = Some(subst_region),
-                Some(lr) => {
-                    if free_region_relations.sub_free_regions(self.tcx, lr, subst_region) {
-                        // keep the current least region
-                    } else if free_region_relations.sub_free_regions(self.tcx, subst_region, lr) {
-                        // switch to `subst_region`
-                        least_region = Some(subst_region);
-                    } else {
-                        // There are two regions (`lr` and
-                        // `subst_region`) which are not relatable. We
-                        // can't find a best choice. Therefore,
-                        // instead of creating a single bound like
-                        // `'r: 'a` (which is our preferred choice),
-                        // we will create a "in bound" like `'r in
-                        // ['a, 'b, 'c]`, where `'a..'c` are the
-                        // regions that appear in the impl trait.
-
-                        return self.generate_member_constraint(
-                            concrete_ty,
-                            opaque_defn,
-                            opaque_type_key,
-                            first_own_region,
-                        );
-                    }
-                }
-            }
-        }
-
-        let least_region = least_region.unwrap_or(tcx.lifetimes.re_static);
-        debug!(?least_region);
-
-        if let GenerateMemberConstraints::IfNoStaticBound = mode {
-            if least_region != tcx.lifetimes.re_static {
-                self.generate_member_constraint(
-                    concrete_ty,
-                    opaque_defn,
-                    opaque_type_key,
-                    first_own_region,
-                );
-            }
-        }
-        concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
-            tcx,
-            op: |r| self.sub_regions(infer::CallReturn(span), least_region, r),
-        });
     }
 
     /// As a fallback, we sometimes generate an "in constraint". For
diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs
index 79443010fbb..85602f11593 100644
--- a/compiler/rustc_typeck/src/check/regionck.rs
+++ b/compiler/rustc_typeck/src/check/regionck.rs
@@ -296,7 +296,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         self.visit_body(body);
         self.visit_region_obligations(body_id.hir_id);
 
-        self.constrain_opaque_types(self.outlives_environment.free_region_map());
+        self.constrain_opaque_types();
     }
 
     fn visit_region_obligations(&mut self, hir_id: hir::HirId) {
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
index b6841da1f0b..9b0018d8904 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
@@ -1,13 +1,31 @@
 error: lifetime may not live long enough
-  --> $DIR/ret-impl-trait-one.rs:10:65
+  --> $DIR/ret-impl-trait-one.rs:10:85
+   |
+LL |   async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+   |  ________________________________--__--_______________________________________________^
+   | |                                |   |
+   | |                                |   lifetime `'b` defined here
+   | |                                lifetime `'a` defined here
+LL | |
+LL | |     (a, b)
+LL | | }
+   | |_^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ret-impl-trait-one.rs:16:65
    |
 LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
-   |                                --  --                           ^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a`
-   |                                |   |
-   |                                |   lifetime `'b` defined here
-   |                                lifetime `'a` defined here
+   |                                    --                           ^^^^^^^^^^^^^^
+   |                                    |
+   |                                    hidden type `(&'a u8, &'b u8)` captures the lifetime `'b` as defined here
+   |
+help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
    |
-   = help: consider adding the following bound: `'b: 'a`
+LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+   |                                                                                ++++
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs
index 7e084217c26..e2d00d8c9c4 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs
@@ -6,9 +6,16 @@
 trait Trait<'a> { }
 impl<T> Trait<'_> for T { }
 
+// Fails to recognize that both 'a and 'b are mentioned and should thus be accepted
+async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+    //~^ ERROR lifetime mismatch
+    (a, b)
+}
+
 // Only `'a` permitted in return type, not `'b`.
 async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
-    //~^ ERROR lifetime mismatch
+    //~^ ERROR captures lifetime that does not appear in bounds
+    //~| ERROR captures lifetime that does not appear in bounds
     (a, b)
 }
 
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
index 8e28605721c..8d2a8e8f1d8 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
@@ -1,13 +1,40 @@
 error[E0623]: lifetime mismatch
   --> $DIR/ret-impl-trait-one.rs:10:65
    |
+LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+   |                                                      ------     ^^^^^^^^^^^^^^^^^^^
+   |                                                      |          |
+   |                                                      |          ...but data from `a` is held across an await point here
+   |                                                      |          this `async fn` implicitly returns an `impl Future<Output = impl Trait<'a> + 'b>`
+   |                                                      this parameter and the returned future are declared with different lifetimes...
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ret-impl-trait-one.rs:16:65
+   |
 LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
-   |                                           ------                ^^^^^^^^^^^^^^
-   |                                           |                     |
-   |                                           |                     ...but data from `b` is held across an await point here
-   |                                           |                     this `async fn` implicitly returns an `impl Future<Output = impl Trait<'a>>`
-   |                                           this parameter and the returned future are declared with different lifetimes...
+   |                                    --                           ^^^^^^^^^^^^^^
+   |                                    |
+   |                                    hidden type `(&u8, &u8)` captures the lifetime `'b` as defined here
+   |
+help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
+   |
+LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+   |                                                                                ++++
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ret-impl-trait-one.rs:16:65
+   |
+LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> {
+   |                                    --                           ^^^^^^^^^^^^^^
+   |                                    |
+   |                                    hidden type `(&u8, &u8)` captures the lifetime `'b` as defined here
+   |
+help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
+   |
+LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+   |                                                                                ++++
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0623`.
+Some errors have detailed explanations: E0623, E0700.
+For more information about an error, try `rustc --explain E0623`.
diff --git a/src/test/ui/impl-trait/hidden-lifetimes.nll.stderr b/src/test/ui/impl-trait/hidden-lifetimes.nll.stderr
new file mode 100644
index 00000000000..60d3409a8ac
--- /dev/null
+++ b/src/test/ui/impl-trait/hidden-lifetimes.nll.stderr
@@ -0,0 +1,29 @@
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/hidden-lifetimes.rs:28:54
+   |
+LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a {
+   |                 --                                   ^^^^^^^^^^^^^^
+   |                 |
+   |                 hidden type `&'a mut &'b T` captures the lifetime `'b` as defined here
+   |
+help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
+   |
+LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a + 'b {
+   |                                                                     ++++
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/hidden-lifetimes.rs:45:70
+   |
+LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
+   |                        --                                            ^^^^^^^^^^^^^^
+   |                        |
+   |                        hidden type `Rc<RefCell<&'b T>>` captures the lifetime `'b` as defined here
+   |
+help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
+   |
+LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a + 'b {
+   |                                                                                     ++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/impl-trait/hidden-lifetimes.stderr b/src/test/ui/impl-trait/hidden-lifetimes.stderr
index 60d3409a8ac..bba92038700 100644
--- a/src/test/ui/impl-trait/hidden-lifetimes.stderr
+++ b/src/test/ui/impl-trait/hidden-lifetimes.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a {
    |                 --                                   ^^^^^^^^^^^^^^
    |                 |
-   |                 hidden type `&'a mut &'b T` captures the lifetime `'b` as defined here
+   |                 hidden type `&mut &'b T` captures the lifetime `'b` as defined here
    |
 help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
    |
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
index 812093e6e76..479874695a7 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
@@ -1,31 +1,31 @@
-error: lifetime may not live long enough
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/must_outlive_least_region_or_bound.rs:3:23
    |
 LL | fn elided(x: &i32) -> impl Copy { x }
-   |              -        ^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+   |              ----     ^^^^^^^^^
    |              |
-   |              let's call the lifetime of this reference `'1`
+   |              hidden type `&i32` captures the anonymous lifetime defined here
    |
-help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
+help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound
    |
 LL | fn elided(x: &i32) -> impl Copy + '_ { x }
    |                                 ++++
 
-error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:5:32
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/must_outlive_least_region_or_bound.rs:6:32
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
-   |             --                 ^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
+   |             --                 ^^^^^^^^^
    |             |
-   |             lifetime `'a` defined here
+   |             hidden type `&'a i32` captures the lifetime `'a` as defined here
    |
-help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
+help: to declare that the `impl Trait` captures 'a, you can add an explicit `'a` lifetime bound
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
    |                                          ++++
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:7:46
+  --> $DIR/must_outlive_least_region_or_bound.rs:9:46
    |
 LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |               -                              ^ returning this value requires that `'1` must outlive `'static`
@@ -35,7 +35,7 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    = help: consider replacing `'1` with `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:9:55
+  --> $DIR/must_outlive_least_region_or_bound.rs:11:55
    |
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |              -- lifetime `'a` defined here            ^ returning this value requires that `'a` must outlive `'static`
@@ -43,7 +43,7 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    = help: consider replacing `'a` with `'static`
 
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/must_outlive_least_region_or_bound.rs:11:41
+  --> $DIR/must_outlive_least_region_or_bound.rs:13:41
    |
 LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
    |               ----                      ^ lifetime `'a` required
@@ -51,33 +51,36 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
    |               help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:22:24
+  --> $DIR/must_outlive_least_region_or_bound.rs:24:55
    |
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
-   |               -        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+   |               -                                       ^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
    |               |
    |               let's call the lifetime of this reference `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:28:69
+  --> $DIR/must_outlive_least_region_or_bound.rs:30:69
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    |               -- lifetime `'a` defined here                         ^ returning this value requires that `'a` must outlive `'static`
    |
    = help: consider replacing `'a` with `'static`
 
-error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:32:61
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/must_outlive_least_region_or_bound.rs:34:61
    |
 LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
-   |                          --  -- lifetime `'b` defined here  ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a`
-   |                          |
-   |                          lifetime `'a` defined here
+   |                              --                             ^^^^^^^^^^^^^^^^
+   |                              |
+   |                              hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:37:5: 37:31]` captures the lifetime `'b` as defined here
+   |
+help: to declare that the `impl Trait` captures 'b, you can add an explicit `'b` lifetime bound
    |
-   = help: consider adding the following bound: `'b: 'a`
+LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) + 'b {
+   |                                                                              ++++
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:37:51
+  --> $DIR/must_outlive_least_region_or_bound.rs:40:51
    |
 LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
    |                                                   ^^^^^^^^^^^^^^^^^^^^
@@ -86,5 +89,5 @@ LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
 
 error: aborting due to 9 previous errors
 
-Some errors have detailed explanations: E0310, E0621.
+Some errors have detailed explanations: E0310, E0621, E0700.
 For more information about an error, try `rustc --explain E0310`.
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
index 51f488e45a6..d30e0191840 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
@@ -1,8 +1,10 @@
 use std::fmt::Debug;
 
-fn elided(x: &i32) -> impl Copy { x } //~ ERROR E0759
+fn elided(x: &i32) -> impl Copy { x }
+//~^ ERROR: captures lifetime that does not appear in bounds
 
-fn explicit<'a>(x: &'a i32) -> impl Copy { x } //~ ERROR E0759
+fn explicit<'a>(x: &'a i32) -> impl Copy { x }
+//~^ ERROR: captures lifetime that does not appear in bounds
 
 fn elided2(x: &i32) -> impl Copy + 'static { x } //~ ERROR E0759
 
@@ -20,7 +22,7 @@ fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) } //~ ERROR E0759
 fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) } //~ ERROR E0759
 
 fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) } //~ ERROR E0759
-//~^ ERROR E0759
+//~^ ERROR: captures lifetime that does not appear in bounds
 
 trait LifetimeTrait<'a> {}
 impl<'a> LifetimeTrait<'a> for &'a i32 {}
@@ -30,7 +32,8 @@ fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } //~ ERRO
 // Tests that a closure type containing 'b cannot be returned from a type where
 // only 'a was expected.
 fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
-    //~^ ERROR lifetime mismatch
+    //~^ ERROR: captures lifetime that does not appear in bounds
+    //~| ERROR: captures lifetime that does not appear in bounds
     move |_| println!("{}", y)
 }
 
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 81ba89b0e05..b472132a12b 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
@@ -1,41 +1,29 @@
-error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:3:35
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/must_outlive_least_region_or_bound.rs:3:23
    |
 LL | fn elided(x: &i32) -> impl Copy { x }
-   |              ----                 ^ ...is captured here...
-   |              |
-   |              this data with an anonymous lifetime `'_`...
+   |                       ^^^^^^^^^
    |
-note: ...and is required to live as long as `'static` here
+note: hidden type `&i32` captures lifetime smaller than the function body
   --> $DIR/must_outlive_least_region_or_bound.rs:3:23
    |
 LL | fn elided(x: &i32) -> impl Copy { x }
    |                       ^^^^^^^^^
-help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound
-   |
-LL | fn elided(x: &i32) -> impl Copy + '_ { x }
-   |                                 ++++
 
-error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:5:44
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/must_outlive_least_region_or_bound.rs:6:32
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
-   |                    -------                 ^ ...is captured here...
-   |                    |
-   |                    this data with lifetime `'a`...
+   |                                ^^^^^^^^^
    |
-note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:5:32
+note: hidden type `&i32` captures lifetime smaller than the function body
+  --> $DIR/must_outlive_least_region_or_bound.rs:6:32
    |
 LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
    |                                ^^^^^^^^^
-help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'a` lifetime bound
-   |
-LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
-   |                                          ++++
 
 error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:7:46
+  --> $DIR/must_outlive_least_region_or_bound.rs:9:46
    |
 LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |               ----                           ^ ...is captured here...
@@ -43,7 +31,7 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |               this data with an anonymous lifetime `'_`...
    |
 note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:7:24
+  --> $DIR/must_outlive_least_region_or_bound.rs:9:24
    |
 LL | fn elided2(x: &i32) -> impl Copy + 'static { x }
    |                        ^^^^^^^^^^^^^^^^^^^
@@ -57,7 +45,7 @@ LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x }
    |               ~~~~~~~~~~~~
 
 error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:9:55
+  --> $DIR/must_outlive_least_region_or_bound.rs:11:55
    |
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |                     -------                           ^ ...is captured here...
@@ -65,7 +53,7 @@ LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |                     this data with lifetime `'a`...
    |
 note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:9:33
+  --> $DIR/must_outlive_least_region_or_bound.rs:11:33
    |
 LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x }
    |                                 ^^^^^^^^^^^^^^^^^^^
@@ -79,39 +67,31 @@ LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x }
    |                     ~~~~~~~~~~~~
 
 error[E0621]: explicit lifetime required in the type of `x`
-  --> $DIR/must_outlive_least_region_or_bound.rs:11:24
+  --> $DIR/must_outlive_least_region_or_bound.rs:13:24
    |
 LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
    |               ----     ^^^^^^^^^^^^^^ lifetime `'a` required
    |               |
    |               help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
 
-error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:22:65
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/must_outlive_least_region_or_bound.rs:24:41
    |
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
-   |               ---- this data with an anonymous lifetime `'_`... ^ ...is captured here, requiring it to live as long as `'static`
+   |                                         ^^^^^^^^^^
    |
-help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
+note: hidden type `&i32` captures lifetime smaller than the function body
+  --> $DIR/must_outlive_least_region_or_bound.rs:24:41
    |
-LL | fn elided5(x: &i32) -> (Box<dyn Debug + '_>, impl Debug) { (Box::new(x), x) }
-   |                                       ++++
-help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound
-   |
-LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x) }
-   |                                                    ++++
+LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
+   |                                         ^^^^^^^^^^
 
 error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:22:69
+  --> $DIR/must_outlive_least_region_or_bound.rs:24:65
    |
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
-   |               ---- this data with an anonymous lifetime `'_`...     ^ ...is captured here...
-   |
-note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:22:41
+   |               ---- this data with an anonymous lifetime `'_`... ^ ...is captured here, requiring it to live as long as `'static`
    |
-LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
-   |                                         ^^^^^^^^^^
 help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
    |
 LL | fn elided5(x: &i32) -> (Box<dyn Debug + '_>, impl Debug) { (Box::new(x), x) }
@@ -122,13 +102,13 @@ LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x)
    |                                                    ++++
 
 error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:28:69
+  --> $DIR/must_outlive_least_region_or_bound.rs:30:69
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    |                      ------- this data with lifetime `'a`...        ^ ...is captured here...
    |
 note: ...and is required to live as long as `'static` here
-  --> $DIR/must_outlive_least_region_or_bound.rs:28:34
+  --> $DIR/must_outlive_least_region_or_bound.rs:30:34
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -141,17 +121,32 @@ help: alternatively, add an explicit `'static` bound to this reference
 LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x }
    |                      ~~~~~~~~~~~~
 
-error[E0623]: lifetime mismatch
-  --> $DIR/must_outlive_least_region_or_bound.rs:32:61
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/must_outlive_least_region_or_bound.rs:34:61
    |
 LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
-   |                                                 -------     ^^^^^^^^^^^^^^^^
-   |                                                 |           |
-   |                                                 |           ...but data from `y` is returned here
-   |                                                 this parameter and the return type are declared with different lifetimes...
+   |                                                             ^^^^^^^^^^^^^^^^
+   |
+note: hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:37:5: 37:31]` captures lifetime smaller than the function body
+  --> $DIR/must_outlive_least_region_or_bound.rs:34:61
+   |
+LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
+   |                                                             ^^^^^^^^^^^^^^^^
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/must_outlive_least_region_or_bound.rs:34:61
+   |
+LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
+   |                                                             ^^^^^^^^^^^^^^^^
+   |
+note: hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:37:5: 37:31]` captures lifetime smaller than the function body
+  --> $DIR/must_outlive_least_region_or_bound.rs:34:61
+   |
+LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
+   |                                                             ^^^^^^^^^^^^^^^^
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:37:51
+  --> $DIR/must_outlive_least_region_or_bound.rs:40: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
@@ -159,7 +154,7 @@ LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
    |                                 help: consider adding an explicit lifetime bound...: `T: 'static +`
 
 error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:14:50
+  --> $DIR/must_outlive_least_region_or_bound.rs:16:50
    |
 LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
    |               ----                               ^ ...is captured here, requiring it to live as long as `'static`
@@ -172,7 +167,7 @@ LL | fn elided3(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
    |                                      ++++
 
 error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:16:59
+  --> $DIR/must_outlive_least_region_or_bound.rs:18:59
    |
 LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
    |                     -------                               ^ ...is captured here, requiring it to live as long as `'static`
@@ -185,7 +180,7 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
    |                                               ++++
 
 error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:18:60
+  --> $DIR/must_outlive_least_region_or_bound.rs:20:60
    |
 LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |               ----                                         ^ ...is captured here, requiring it to live as long as `'static`
@@ -202,7 +197,7 @@ LL | fn elided4(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |               ~~~~~~~~~~~~
 
 error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/must_outlive_least_region_or_bound.rs:20:69
+  --> $DIR/must_outlive_least_region_or_bound.rs:22:69
    |
 LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |                     ------- this data with lifetime `'a`...         ^ ...is captured here, requiring it to live as long as `'static`
@@ -216,7 +211,7 @@ help: alternatively, add an explicit `'static` bound to this reference
 LL | fn explicit4<'a>(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
    |                     ~~~~~~~~~~~~
 
-error: aborting due to 14 previous errors
+error: aborting due to 15 previous errors
 
-Some errors have detailed explanations: E0310, E0621, E0623, E0759.
+Some errors have detailed explanations: E0310, E0621, E0700, E0759.
 For more information about an error, try `rustc --explain E0310`.
diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
index a3aeff50eee..3d435bd1c3f 100644
--- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
+++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
@@ -1,28 +1,55 @@
-error: lifetime may not live long enough
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/static-return-lifetime-infered.rs:6:35
    |
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
-   |                         -         ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+   |                         -----     ^^^^^^^^^^^^^^^^^^^^^^^
    |                         |
-   |                         let's call the lifetime of this reference `'1`
+   |                         hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:11:27: 11:34]>` captures the anonymous lifetime defined here
    |
-help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
+help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound
    |
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
    |                                                           ++++
 
-error: lifetime may not live long enough
-  --> $DIR/static-return-lifetime-infered.rs:9:37
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:6:35
+   |
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+   |                         -----     ^^^^^^^^^^^^^^^^^^^^^^^
+   |                         |
+   |                         hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:11:27: 11:34]>` captures the anonymous lifetime defined here
+   |
+help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound
+   |
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
+   |                                                           ++++
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:13:37
+   |
+LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
+   |                    --               ^^^^^^^^^^^^^^^^^^^^^^^
+   |                    |
+   |                    hidden type `Map<std::slice::Iter<'a, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:18:27: 18:34]>` captures the lifetime `'a` as defined here
+   |
+help: to declare that the `impl Trait` captures 'a, you can add an explicit `'a` lifetime bound
+   |
+LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
+   |                                                             ++++
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:13:37
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
-   |                    --               ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
+   |                    --               ^^^^^^^^^^^^^^^^^^^^^^^
    |                    |
-   |                    lifetime `'a` defined here
+   |                    hidden type `Map<std::slice::Iter<'a, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:18:27: 18:34]>` captures the lifetime `'a` as defined here
    |
-help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
+help: to declare that the `impl Trait` captures 'a, you can add an explicit `'a` lifetime bound
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
    |                                                             ++++
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.rs b/src/test/ui/impl-trait/static-return-lifetime-infered.rs
index 518c52f5de4..e204cb0f7a7 100644
--- a/src/test/ui/impl-trait/static-return-lifetime-infered.rs
+++ b/src/test/ui/impl-trait/static-return-lifetime-infered.rs
@@ -4,10 +4,18 @@ struct A {
 
 impl A {
     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
-        self.x.iter().map(|a| a.0) //~ ERROR E0759
+        //~^ ERROR: captures lifetime that does not appear in bounds
+        //~| ERROR: captures lifetime that does not appear in bounds
+        //~| ERROR: captures lifetime that does not appear in bounds
+        //~| ERROR: captures lifetime that does not appear in bounds
+        self.x.iter().map(|a| a.0)
     }
     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
-        self.x.iter().map(|a| a.0) //~ ERROR E0759
+        //~^ ERROR: captures lifetime that does not appear in bounds
+        //~| ERROR: captures lifetime that does not appear in bounds
+        //~| ERROR: captures lifetime that does not appear in bounds
+        //~| ERROR: captures lifetime that does not appear in bounds
+        self.x.iter().map(|a| a.0)
     }
 }
 
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 ebd0b6a1281..33502bcf7d0 100644
--- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
+++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
@@ -1,43 +1,99 @@
-error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/static-return-lifetime-infered.rs:7:16
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:6:35
+   |
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:11:27: 11:34]>` captures lifetime smaller than the function body
+  --> $DIR/static-return-lifetime-infered.rs:6:35
+   |
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:6:35
    |
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
-   |                         ----- this data with an anonymous lifetime `'_`...
-LL |         self.x.iter().map(|a| a.0)
-   |         ------ ^^^^
-   |         |
-   |         ...is captured here...
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:11:27: 11:34]>` captures lifetime smaller than the function body
+  --> $DIR/static-return-lifetime-infered.rs:6:35
    |
-note: ...and is required to live as long as `'static` here
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/static-return-lifetime-infered.rs:6:35
    |
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^
-help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
    |
-LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
-   |                                                           ++++
+note: hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:11:27: 11:34]>` captures lifetime smaller than the function body
+  --> $DIR/static-return-lifetime-infered.rs:6:35
+   |
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0759]: `self` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/static-return-lifetime-infered.rs:10:16
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:6:35
+   |
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:11:27: 11:34]>` captures lifetime smaller than the function body
+  --> $DIR/static-return-lifetime-infered.rs:6:35
+   |
+LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:13:37
+   |
+LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:18:27: 18:34]>` captures lifetime smaller than the function body
+  --> $DIR/static-return-lifetime-infered.rs:13:37
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
-   |                        -------- this data with lifetime `'a`...
-LL |         self.x.iter().map(|a| a.0)
-   |         ------ ^^^^
-   |         |
-   |         ...is captured here...
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:13:37
    |
-note: ...and is required to live as long as `'static` here
-  --> $DIR/static-return-lifetime-infered.rs:9:37
+LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:18:27: 18:34]>` captures lifetime smaller than the function body
+  --> $DIR/static-return-lifetime-infered.rs:13:37
    |
 LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^
-help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:13:37
    |
-LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
-   |                                                             ++++
+LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:18:27: 18:34]>` captures lifetime smaller than the function body
+  --> $DIR/static-return-lifetime-infered.rs:13:37
+   |
+LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/static-return-lifetime-infered.rs:13:37
+   |
+LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:18:27: 18:34]>` captures lifetime smaller than the function body
+  --> $DIR/static-return-lifetime-infered.rs:13:37
+   |
+LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0759`.
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/nll/issue-73159-rpit-static.rs b/src/test/ui/nll/issue-73159-rpit-static.rs
index a5455a3f9eb..e29ba09b369 100644
--- a/src/test/ui/nll/issue-73159-rpit-static.rs
+++ b/src/test/ui/nll/issue-73159-rpit-static.rs
@@ -6,7 +6,8 @@
 struct Foo<'a>(&'a [u8]);
 
 impl<'a> Foo<'a> {
-    fn make_it(&self) -> impl Iterator<Item = u8> { //~ ERROR lifetime may not live
+    fn make_it(&self) -> impl Iterator<Item = u8> {
+        //~^ ERROR: captures lifetime that does not appear in bounds
         self.0.iter().copied()
     }
 }
diff --git a/src/test/ui/nll/issue-73159-rpit-static.stderr b/src/test/ui/nll/issue-73159-rpit-static.stderr
index 60b1552701a..6c7cd0c8254 100644
--- a/src/test/ui/nll/issue-73159-rpit-static.stderr
+++ b/src/test/ui/nll/issue-73159-rpit-static.stderr
@@ -1,10 +1,11 @@
-error: lifetime may not live long enough
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/issue-73159-rpit-static.rs:9:26
    |
 LL | impl<'a> Foo<'a> {
-   |      -- lifetime `'a` defined here
+   |      -- hidden type `Copied<std::slice::Iter<'a, u8>>` captures the lifetime `'a` as defined here
 LL |     fn make_it(&self) -> impl Iterator<Item = u8> {
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs
index bcdf643c0b9..8af23aad726 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs
+++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs
@@ -8,7 +8,7 @@ trait Foo<'a> {
 impl<'a, T> Foo<'a> for T { }
 
 fn foo<'a, T>(x: &T) -> impl Foo<'a> {
-//~^ ERROR explicit lifetime required in the type of `x` [E0621]
+//~^ ERROR captures lifetime that does not appear in bounds
     x
 }
 
diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
index d05fc793967..21d1eea54e6 100644
--- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
+++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr
@@ -1,14 +1,16 @@
-error[E0621]: explicit lifetime required in the type of `x`
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/impl-trait-captures.rs:10:25
    |
 LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> {
-   |                         ^^^^^^^^^^^^ lifetime `ReEarlyBound(0, 'a)` required
+   |                  --     ^^^^^^^^^^^^
+   |                  |
+   |                  hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[e9f4]::foo), BrAnon(0)) T` captures the anonymous lifetime defined here
    |
-help: add explicit lifetime `ReEarlyBound(0, 'a)` to the type of `x`
+help: to declare that the `impl Trait` captures ReFree(DefId(0:8 ~ impl_trait_captures[e9f4]::foo), BrAnon(0)), you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[e9f4]::foo), BrAnon(0))` lifetime bound
    |
-LL | fn foo<'a, T>(x: &ReEarlyBound(0, 'a) T) -> impl Foo<'a> {
-   |                  ~~~~~~~~~~~~~~~~~~~~~~
+LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReFree(DefId(0:8 ~ impl_trait_captures[e9f4]::foo), BrAnon(0)) {
+   |                                      ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0621`.
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
index 5d0b2c2ebdf..953d7cd6a07 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
@@ -1,15 +1,16 @@
-error: lifetime may not live long enough
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
-   |                          -          ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+   |                          -          ^^^^^^^^^^
    |                          |
-   |                          let's call the lifetime of this reference `'1`
+   |                          hidden type `Pin<&Foo>` captures the lifetime `'_` as defined here
    |
-help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
+help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
    |                                                ++++
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
index 43998ca8c57..e3483e4e62a 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
@@ -6,7 +6,8 @@ struct Foo;
 
 impl Foo {
     async fn f(self: Pin<&Self>) -> impl Clone { self }
-    //~^ ERROR E0759
+    //~^ ERROR: captures lifetime that does not appear in bounds
+    //~| ERROR: captures lifetime that does not appear in bounds
 }
 
 fn main() {
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 04cd2b78da1..aac585ca414 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
@@ -1,17 +1,29 @@
-error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
-   |                ^^^^  ----------     ---------- ...and is required to live as long as `'static` here
-   |                |     |
-   |                |     this data with an anonymous lifetime `'_`...
-   |                ...is captured here...
+   |                          -          ^^^^^^^^^^
+   |                          |
+   |                          hidden type `Pin<&Foo>` captures the lifetime `'_` as defined here
    |
-help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
+help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
    |                                                ++++
 
-error: aborting due to previous error
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:37
+   |
+LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
+   |                          -          ^^^^^^^^^^
+   |                          |
+   |                          hidden type `Pin<&Foo>` captures the lifetime `'_` as defined here
+   |
+help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound
+   |
+LL |     async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
+   |                                                ++++
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0759`.
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
index 4301d8f767a..faa1233ffde 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr
@@ -1,15 +1,16 @@
-error: lifetime may not live long enough
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
-   |                    -          ^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+   |                    -----      ^^^^^^^^^^
    |                    |
-   |                    let's call the lifetime of this reference `'1`
+   |                    hidden type `Pin<&Foo>` captures the anonymous lifetime defined here
    |
-help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
+help: to declare that the `impl Trait` captures '_, you can add an explicit `'_` lifetime bound
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
    |                                          ++++
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs
index 04935fc52ab..4db2fa7dcb8 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs
@@ -3,7 +3,8 @@ use std::pin::Pin;
 struct Foo;
 
 impl Foo {
-    fn f(self: Pin<&Self>) -> impl Clone { self } //~ ERROR E0759
+    fn f(self: Pin<&Self>) -> impl Clone { self }
+    //~^ ERROR: captures lifetime that does not appear in bounds
 }
 
 fn main() {
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 54e75aeec3e..7b645f51fe0 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
@@ -1,21 +1,15 @@
-error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
-   |                ----------                  ^^^^ ...is captured here...
-   |                |
-   |                this data with an anonymous lifetime `'_`...
+   |                               ^^^^^^^^^^
    |
-note: ...and is required to live as long as `'static` here
+note: hidden type `Pin<&Foo>` captures lifetime smaller than the function body
   --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:31
    |
 LL |     fn f(self: Pin<&Self>) -> impl Clone { self }
    |                               ^^^^^^^^^^
-help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
-   |
-LL |     fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
-   |                                          ++++
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0759`.
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr
index 80d3c940eb7..2dc300ac76f 100644
--- a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr
+++ b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.nll.stderr
@@ -1,17 +1,8 @@
-error[E0597]: `val` does not live long enough
+error[E0515]: cannot return reference to function parameter `val`
   --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:21:9
    |
-LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> {
-   |               -- lifetime `'a` defined here                  ------------------- opaque type requires that `val` is borrowed for `'a`
 LL |         val.use_self()
-   |         ^^^^^^^^^^^^^^ borrowed value does not live long enough
-LL |     }
-   |     - `val` dropped here while still borrowed
-   |
-help: you can add a bound to the opaque type to make it last less than `'static` and match `'a`
-   |
-LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> + 'a {
-   |                                                                                  ++++
+   |         ^^^^^^^^^^^^^^ returns a reference to data owned by the current function
 
 error[E0515]: cannot return reference to function parameter `val`
   --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:43:9
@@ -27,5 +18,4 @@ LL |         val.use_self()
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0515, E0597.
-For more information about an error, try `rustc --explain E0515`.
+For more information about this error, try `rustc --explain E0515`.
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs
index b2dc16a27e3..0045d3fcf1c 100644
--- a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs
+++ b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs
@@ -18,7 +18,7 @@ mod bav {
     impl Bar for i32 {}
 
     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> {
-        val.use_self() //~ ERROR E0597
+        val.use_self() //~ ERROR cannot return reference to function parameter
     }
 }
 
diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr
index e8c3a7908f5..2961d8d7eac 100644
--- a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr
+++ b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr
@@ -1,17 +1,8 @@
-error[E0597]: `val` does not live long enough
+error[E0515]: cannot return reference to function parameter `val`
   --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:21:9
    |
-LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> {
-   |               -- lifetime `'a` defined here                  ------------------- opaque type requires that `val` is borrowed for `'a`
 LL |         val.use_self()
-   |         ^^^^^^^^^^^^^^ borrowed value does not live long enough
-LL |     }
-   |     - `val` dropped here while still borrowed
-   |
-help: you can add a bound to the opaque type to make it last less than `'static` and match `'a`
-   |
-LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> + 'a {
-   |                                                                                  ++++
+   |         ^^^^^^^^^^^^^^ returns a reference to data owned by the current function
 
 error[E0515]: cannot return reference to function parameter `val`
   --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:43:9
@@ -47,5 +38,4 @@ LL |     impl MyTrait for Box<dyn ObjectTrait<Assoc = i32> + '_> {
 
 error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0515, E0597.
-For more information about an error, try `rustc --explain E0515`.
+For more information about this error, try `rustc --explain E0515`.
diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
index b579635ca7c..3ed3827b97d 100644
--- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
+++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
@@ -1,10 +1,13 @@
 error: lifetime may not live long enough
-  --> $DIR/trait-object-nested-in-impl-trait.rs:27:23
+  --> $DIR/trait-object-nested-in-impl-trait.rs:28:9
    |
-LL |     fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
-   |             -         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
-   |             |
-   |             let's call the lifetime of this reference `'1`
+LL |       fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
+   |               - let's call the lifetime of this reference `'1`
+LL | /         Iter {
+LL | |             current: None,
+LL | |             remaining: self.0.iter(),
+LL | |         }
+   | |_________^ returning this value requires that `'1` must outlive `'static`
    |
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
    |
@@ -34,12 +37,15 @@ LL | |         }
    | |_________^ returning this value requires that `'a` must outlive `'static`
 
 error: lifetime may not live long enough
-  --> $DIR/trait-object-nested-in-impl-trait.rs:60:30
+  --> $DIR/trait-object-nested-in-impl-trait.rs:61:9
    |
-LL |     fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
-   |             --               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
-   |             |
-   |             lifetime `'a` defined here
+LL |       fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
+   |               -- lifetime `'a` defined here
+LL | /         Iter {
+LL | |             current: None,
+LL | |             remaining: self.0.iter(),
+LL | |         }
+   | |_________^ returning this value requires that `'a` must outlive `'static`
    |
 help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
    |