about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-03-08 08:19:20 +0100
committerGitHub <noreply@github.com>2024-03-08 08:19:20 +0100
commitd4d18d240b4c2f5c7b97a6eba05d686e003bf718 (patch)
treec24bf9798888669fbf91f1caf987621ad7fedfb4
parentd16c55d6f608848231314151648b38b424f9297f (diff)
parent74d5bbbf94418d87def5acd89343b63d36ada5e0 (diff)
downloadrust-d4d18d240b4c2f5c7b97a6eba05d686e003bf718.tar.gz
rust-d4d18d240b4c2f5c7b97a6eba05d686e003bf718.zip
Rollup merge of #122103 - compiler-errors:taits-capture-everything, r=oli-obk
Make TAITs and ATPITs capture late-bound lifetimes in scope

This generalizes the behavior that RPITs have, where they duplicate their in-scope lifetimes so that they will always *reify* late-bound lifetimes that they capture. This allows TAITs and ATPITs to properly error when they capture in-scope late-bound lifetimes.

r? `@oli-obk` cc `@aliemjay`

Fixes #122093 and therefore https://github.com/rust-lang/rust/pull/120700#issuecomment-1981213868
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs16
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs58
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs19
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs56
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs10
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs20
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs12
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs2
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/escaping-bound-var.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/escaping-bound-var.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/self-referential.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/variance.rs30
-rw-r--r--tests/ui/type-alias-impl-trait/variance.stderr45
21 files changed, 148 insertions, 185 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 01b1e6fcaff..52300138186 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -275,7 +275,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         }
                         Some(ty) => this.lower_ty(
                             ty,
-                            ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
+                            ImplTraitContext::OpaqueTy {
+                                origin: hir::OpaqueTyOrigin::TyAlias {
+                                    parent: this.local_def_id(id),
+                                    in_assoc_ty: false,
+                                },
+                                fn_kind: None,
+                            },
                         ),
                     },
                 );
@@ -936,7 +942,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         Some(ty) => {
                             let ty = this.lower_ty(
                                 ty,
-                                ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
+                                ImplTraitContext::OpaqueTy {
+                                    origin: hir::OpaqueTyOrigin::TyAlias {
+                                        parent: this.local_def_id(i.id),
+                                        in_assoc_ty: true,
+                                    },
+                                    fn_kind: None,
+                                },
                             );
                             hir::ImplItemKind::Type(ty)
                         }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 03ad75ca8b4..94e1e06a954 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -265,13 +265,12 @@ enum ImplTraitContext {
     /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
     /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
     ///
-    ReturnPositionOpaqueTy {
-        /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
+    OpaqueTy {
         origin: hir::OpaqueTyOrigin,
-        fn_kind: FnDeclKind,
+        /// Only used to change the lifetime capture rules, since
+        /// RPITIT captures all in scope, RPIT does not.
+        fn_kind: Option<FnDeclKind>,
     },
-    /// Impl trait in type aliases.
-    TypeAliasesOpaqueTy { in_assoc_ty: bool },
     /// `impl Trait` is unstably accepted in this position.
     FeatureGated(ImplTraitPosition, Symbol),
     /// `impl Trait` is not accepted in this position.
@@ -1075,9 +1074,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 // Disallow ATB in dyn types
                 if self.is_in_dyn_type {
                     let suggestion = match itctx {
-                        ImplTraitContext::ReturnPositionOpaqueTy { .. }
-                        | ImplTraitContext::TypeAliasesOpaqueTy { .. }
-                        | ImplTraitContext::Universal => {
+                        ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
                             let bound_end_span = constraint
                                 .gen_args
                                 .as_ref()
@@ -1417,24 +1414,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             TyKind::ImplTrait(def_node_id, bounds) => {
                 let span = t.span;
                 match itctx {
-                    ImplTraitContext::ReturnPositionOpaqueTy { origin, fn_kind } => self
-                        .lower_opaque_impl_trait(
-                            span,
-                            origin,
-                            *def_node_id,
-                            bounds,
-                            Some(fn_kind),
-                            itctx,
-                        ),
-                    ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
-                        .lower_opaque_impl_trait(
-                            span,
-                            hir::OpaqueTyOrigin::TyAlias { in_assoc_ty },
-                            *def_node_id,
-                            bounds,
-                            None,
-                            itctx,
-                        ),
+                    ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait(
+                        span,
+                        origin,
+                        *def_node_id,
+                        bounds,
+                        fn_kind,
+                        itctx,
+                    ),
                     ImplTraitContext::Universal => {
                         let span = t.span;
 
@@ -1553,9 +1540,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         let captured_lifetimes_to_duplicate = match origin {
             hir::OpaqueTyOrigin::TyAlias { .. } => {
-                // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't duplicate any
-                // lifetimes, since we don't have the issue that any are late-bound.
-                Vec::new()
+                // type alias impl trait and associated type position impl trait were
+                // decided to capture all in-scope lifetimes, which we collect for
+                // all opaques during resolution.
+                self.resolver
+                    .take_extra_lifetime_params(opaque_ty_node_id)
+                    .into_iter()
+                    .map(|(ident, id, _)| Lifetime { id, ident })
+                    .collect()
             }
             hir::OpaqueTyOrigin::FnReturn(..) => {
                 if matches!(
@@ -1823,9 +1815,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         FnDeclKind::Fn
                         | FnDeclKind::Inherent
                         | FnDeclKind::Trait
-                        | FnDeclKind::Impl => ImplTraitContext::ReturnPositionOpaqueTy {
+                        | FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
                             origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)),
-                            fn_kind: kind,
+                            fn_kind: Some(kind),
                         },
                         FnDeclKind::ExternFn => {
                             ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
@@ -1919,9 +1911,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     output,
                     coro,
                     opaque_ty_span,
-                    ImplTraitContext::ReturnPositionOpaqueTy {
+                    ImplTraitContext::OpaqueTy {
                         origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
-                        fn_kind,
+                        fn_kind: Some(fn_kind),
                     },
                 );
                 arena_vec![this; bound]
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 48941a232c2..aeeb4bf9e76 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -423,7 +423,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             // fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
             // //      disallowed --^^^^^^^^^^        allowed --^^^^^^^^^^
             // ```
-            FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. }) => {
+            FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::OpaqueTy { .. }) => {
                 if self.tcx.features().impl_trait_in_fn_trait_return {
                     self.lower_ty(ty, itctx)
                 } else {
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 4b096a59234..12b02c7fcfa 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -367,14 +367,17 @@ fn check_opaque_type_parameter_valid(
     span: Span,
 ) -> Result<(), ErrorGuaranteed> {
     let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id);
-    let is_ty_alias = match opaque_ty_hir.expect_opaque_ty().origin {
-        OpaqueTyOrigin::TyAlias { .. } => true,
-        OpaqueTyOrigin::AsyncFn(..) | OpaqueTyOrigin::FnReturn(..) => false,
+    let (parent, is_ty_alias) = match opaque_ty_hir.expect_opaque_ty().origin {
+        OpaqueTyOrigin::TyAlias { parent, .. } => (parent, true),
+        OpaqueTyOrigin::AsyncFn(parent) | OpaqueTyOrigin::FnReturn(parent) => (parent, false),
     };
 
-    let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
+    let parent_generics = tcx.generics_of(parent);
     let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
-    for (i, arg) in opaque_type_key.args.iter().enumerate() {
+
+    // Only check the parent generics, which will ignore any of the
+    // duplicated lifetime args that come from reifying late-bounds.
+    for (i, arg) in opaque_type_key.args.iter().take(parent_generics.count()).enumerate() {
         if let Err(guar) = arg.error_reported() {
             return Err(guar);
         }
@@ -395,7 +398,7 @@ fn check_opaque_type_parameter_valid(
             seen_params.entry(arg).or_default().push(i);
         } else {
             // Prevent `fn foo() -> Foo<u32>` from being defining.
-            let opaque_param = opaque_generics.param_at(i, tcx);
+            let opaque_param = parent_generics.param_at(i, tcx);
             let kind = opaque_param.kind.descr();
 
             return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam {
@@ -409,10 +412,10 @@ fn check_opaque_type_parameter_valid(
 
     for (_, indices) in seen_params {
         if indices.len() > 1 {
-            let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
+            let descr = parent_generics.param_at(indices[0], tcx).kind.descr();
             let spans: Vec<_> = indices
                 .into_iter()
-                .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
+                .map(|i| tcx.def_span(parent_generics.param_at(i, tcx).def_id))
                 .collect();
             #[allow(rustc::diagnostic_outside_of_impl)]
             #[allow(rustc::untranslatable_diagnostic)]
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index e4a779507f1..7d5b4c0f06d 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2562,6 +2562,8 @@ pub enum OpaqueTyOrigin {
     AsyncFn(LocalDefId),
     /// type aliases: `type Foo = impl Trait;`
     TyAlias {
+        /// The type alias or associated type parent of the TAIT/ATPIT
+        parent: LocalDefId,
         /// associated types in impl blocks for traits.
         in_assoc_ty: bool,
     },
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 748571c12b3..1b24c2b61fd 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -339,8 +339,9 @@ fn check_opaque_meets_bounds<'tcx>(
     origin: &hir::OpaqueTyOrigin,
 ) -> Result<(), ErrorGuaranteed> {
     let defining_use_anchor = match *origin {
-        hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
-        hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id),
+        hir::OpaqueTyOrigin::FnReturn(did)
+        | hir::OpaqueTyOrigin::AsyncFn(did)
+        | hir::OpaqueTyOrigin::TyAlias { parent: did, .. } => did,
     };
     let param_env = tcx.param_env(defining_use_anchor);
 
@@ -351,14 +352,14 @@ fn check_opaque_meets_bounds<'tcx>(
     let ocx = ObligationCtxt::new(&infcx);
 
     let args = match *origin {
-        hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
-            GenericArgs::identity_for_item(tcx, parent).extend_to(
-                tcx,
-                def_id.to_def_id(),
-                |param, _| tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into(),
-            )
-        }
-        hir::OpaqueTyOrigin::TyAlias { .. } => GenericArgs::identity_for_item(tcx, def_id),
+        hir::OpaqueTyOrigin::FnReturn(parent)
+        | hir::OpaqueTyOrigin::AsyncFn(parent)
+        | hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
+            tcx, parent,
+        )
+        .extend_to(tcx, def_id.to_def_id(), |param, _| {
+            tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into()
+        }),
     };
 
     let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index f70bb8c4289..2675eacc06e 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -339,7 +339,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
     predicates: &mut Vec<(ty::Clause<'tcx>, Span)>,
 ) {
     for param in opaque_own_params {
-        let orig_lifetime = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
+        let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
         if let ty::ReEarlyParam(..) = *orig_lifetime {
             let dup_lifetime = ty::Region::new_early_param(
                 tcx,
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index ad8ec1036ef..607ada8b5ed 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -514,38 +514,11 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 // These sorts of items have no lifetime parameters at all.
                 intravisit::walk_item(self, item);
             }
-            hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-                origin: hir::OpaqueTyOrigin::TyAlias { .. },
-                ..
-            }) => {
-                // Opaque types are visited when we visit the
-                // `TyKind::OpaqueDef`, so that they have the lifetimes from
-                // their parent opaque_ty in scope.
-                //
-                // The core idea here is that since OpaqueTys are generated with the impl Trait as
-                // their owner, we can keep going until we find the Item that owns that. We then
-                // conservatively add all resolved lifetimes. Otherwise we run into problems in
-                // cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
-                let parent_item = self.tcx.hir().get_parent_item(item.hir_id());
-                let resolved_lifetimes: &ResolveBoundVars =
-                    self.tcx.resolve_bound_vars(parent_item);
-                // We need to add *all* deps, since opaque tys may want them from *us*
-                for (&owner, defs) in resolved_lifetimes.defs.iter() {
-                    defs.iter().for_each(|(&local_id, region)| {
-                        self.map.defs.insert(hir::HirId { owner, local_id }, *region);
-                    });
-                }
-                for (&owner, late_bound_vars) in resolved_lifetimes.late_bound_vars.iter() {
-                    late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| {
-                        self.record_late_bound_vars(
-                            hir::HirId { owner, local_id },
-                            late_bound_vars.clone(),
-                        );
-                    });
-                }
-            }
             hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
-                origin: hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent),
+                origin:
+                    hir::OpaqueTyOrigin::FnReturn(parent)
+                    | hir::OpaqueTyOrigin::AsyncFn(parent)
+                    | hir::OpaqueTyOrigin::TyAlias { parent, .. },
                 generics,
                 ..
             }) => {
@@ -683,26 +656,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 //                                      the opaque_ty generics
                 let opaque_ty = self.tcx.hir().item(item_id);
                 match &opaque_ty.kind {
-                    hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-                        origin: hir::OpaqueTyOrigin::TyAlias { .. },
-                        ..
-                    }) => {
-                        intravisit::walk_ty(self, ty);
-
-                        // Elided lifetimes and late-bound lifetimes (from the parent)
-                        // are not allowed in non-return position impl Trait
-                        let scope = Scope::LateBoundary {
-                            s: &Scope::TraitRefBoundary { s: self.scope },
-                            what: "type alias impl trait",
-                        };
-                        self.with(scope, |this| intravisit::walk_item(this, opaque_ty));
-
-                        return;
-                    }
-                    hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-                        origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
-                        ..
-                    }) => {}
+                    hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin: _, .. }) => {}
                     i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
                 };
 
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 2217e5280a7..3d54dd6f9f6 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -553,11 +553,11 @@ pub(super) fn type_of_opaque(
         Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
             Node::Item(item) => match item.kind {
                 ItemKind::OpaqueTy(OpaqueTy {
-                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false },
+                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. },
                     ..
                 }) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
                 ItemKind::OpaqueTy(OpaqueTy {
-                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true },
+                    origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. },
                     ..
                 }) => opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id),
                 // Opaque types desugared from `impl Trait`.
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 9618c6d8011..42885b0c832 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -125,15 +125,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
 
     // By default, RPIT are invariant wrt type and const generics, but they are bivariant wrt
     // lifetime generics.
-    let variances = std::iter::repeat(ty::Invariant).take(generics.count());
-
-    let mut variances: Vec<_> = match tcx.opaque_type_origin(item_def_id) {
-        rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {
-            variances.collect()
-        }
-        // But TAIT are invariant for all generics
-        rustc_hir::OpaqueTyOrigin::TyAlias { .. } => return tcx.arena.alloc_from_iter(variances),
-    };
+    let mut variances = vec![ty::Invariant; generics.count()];
 
     // Mark all lifetimes from parent generics as unused (Bivariant).
     // This will be overridden later if required.
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index b6f3c38cb3f..3d6829ba657 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -391,7 +391,7 @@ impl<'tcx> InferCtxt<'tcx> {
             // Anonymous `impl Trait`
             hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
             // Named `type Foo = impl Bar;`
-            hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
+            hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
                 if in_assoc_ty {
                     self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
                 } else {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 4f8e4aa90f4..4a04e677180 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1254,7 +1254,7 @@ impl<'tcx> TyCtxt<'tcx> {
             if self.def_kind(scope) == DefKind::OpaqueTy {
                 // Lifetime params of opaque types are synthetic and thus irrelevant to
                 // diagnostics. Map them back to their origin!
-                region = self.map_rpit_lifetime_to_fn_lifetime(def_id);
+                region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
                 continue;
             }
             break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
@@ -2219,31 +2219,31 @@ impl<'tcx> TyCtxt<'tcx> {
         )
     }
 
-    /// Given the def-id of an early-bound lifetime on an RPIT corresponding to
+    /// Given the def-id of an early-bound lifetime on an opaque corresponding to
     /// a duplicated captured lifetime, map it back to the early- or late-bound
     /// lifetime of the function from which it originally as captured. If it is
     /// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
     /// of the signature.
     // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
     // re-use the generics of the opaque, this function will need to be tweaked slightly.
-    pub fn map_rpit_lifetime_to_fn_lifetime(
+    pub fn map_opaque_lifetime_to_parent_lifetime(
         self,
-        mut rpit_lifetime_param_def_id: LocalDefId,
+        mut opaque_lifetime_param_def_id: LocalDefId,
     ) -> ty::Region<'tcx> {
         debug_assert!(
-            matches!(self.def_kind(rpit_lifetime_param_def_id), DefKind::LifetimeParam),
-            "{rpit_lifetime_param_def_id:?} is a {}",
-            self.def_descr(rpit_lifetime_param_def_id.to_def_id())
+            matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
+            "{opaque_lifetime_param_def_id:?} is a {}",
+            self.def_descr(opaque_lifetime_param_def_id.to_def_id())
         );
 
         loop {
-            let parent = self.local_parent(rpit_lifetime_param_def_id);
+            let parent = self.local_parent(opaque_lifetime_param_def_id);
             let hir::OpaqueTy { lifetime_mapping, .. } =
                 self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
 
             let Some((lifetime, _)) = lifetime_mapping
                 .iter()
-                .find(|(_, duplicated_param)| *duplicated_param == rpit_lifetime_param_def_id)
+                .find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
             else {
                 bug!("duplicated lifetime param should be present");
             };
@@ -2256,7 +2256,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     // of the opaque we mapped from. Continue mapping.
                     if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
                         debug_assert_eq!(self.parent(parent.to_def_id()), new_parent);
-                        rpit_lifetime_param_def_id = ebv.expect_local();
+                        opaque_lifetime_param_def_id = ebv.expect_local();
                         continue;
                     }
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 4edec0e6951..5c2d3973d61 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1940,18 +1940,6 @@ impl<'tcx> TyCtxt<'tcx> {
         matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait))
     }
 
-    /// Returns the `DefId` of the item within which the `impl Trait` is declared.
-    /// For type-alias-impl-trait this is the `type` alias.
-    /// For impl-trait-in-assoc-type this is the assoc type.
-    /// For return-position-impl-trait this is the function.
-    pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId {
-        // Find the surrounding item (type alias or assoc type)
-        while let DefKind::OpaqueTy = self.def_kind(def_id) {
-            def_id = self.local_parent(def_id);
-        }
-        def_id
-    }
-
     pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
         if self.def_kind(def_id) != DefKind::AssocFn {
             return false;
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index 191671bcc1e..87462963c27 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -71,7 +71,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
                     // the end of the list corresponding to the opaque's generics.
                     for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] {
                         let orig_lt =
-                            tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
+                            tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
                         if matches!(*orig_lt, ty::ReLateParam(..)) {
                             mapping.insert(
                                 orig_lt,
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index c6448b4f661..3dcc8382289 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -141,7 +141,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
         trace!(?origin);
         match origin {
             rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
-            rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
+            rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
                 if !in_assoc_ty {
                     if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
                         return;
diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs
index bf27e76db2b..b030ce39d1d 100644
--- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs
+++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs
@@ -7,7 +7,7 @@ pub trait Trait<'a> {
 trait Test<'a> {}
 
 pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
-//~^ ERROR cannot capture late-bound lifetime in type alias impl trait
+//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
 
 impl Trait<'_> for () {
     type Assoc = ();
diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr
index 7dce067d39c..706de37e9f3 100644
--- a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr
+++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr
@@ -1,8 +1,14 @@
-error: cannot capture late-bound lifetime in type alias impl trait
-  --> $DIR/escaping-bound-var.rs:9:57
+error: higher kinded lifetime bounds on nested opaque types are not supported yet
+  --> $DIR/escaping-bound-var.rs:9:25
    |
 LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
-   |                         -- lifetime defined here        ^^
+   |                         ^^
+   |
+note: lifetime declared here
+  --> $DIR/escaping-bound-var.rs:9:25
+   |
+LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
+   |                         ^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/self-referential.rs b/tests/ui/type-alias-impl-trait/self-referential.rs
index 3090f7733d2..2bd450e6c86 100644
--- a/tests/ui/type-alias-impl-trait/self-referential.rs
+++ b/tests/ui/type-alias-impl-trait/self-referential.rs
@@ -12,14 +12,14 @@ fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
 type Foo<'a, 'b> = (i32, impl PartialEq<Foo<'a, 'b>> + std::fmt::Debug);
 
 fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
-    //~^ ERROR can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0})`
+    //~^ ERROR can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
     (42, i)
 }
 
 type Moo<'a, 'b> = (i32, impl PartialEq<Moo<'b, 'a>> + std::fmt::Debug);
 
 fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
-    //~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
+    //~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
     (42, i)
 }
 
diff --git a/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr
index 27506b8d06f..396237c7898 100644
--- a/tests/ui/type-alias-impl-trait/self-referential.stderr
+++ b/tests/ui/type-alias-impl-trait/self-referential.stderr
@@ -10,28 +10,28 @@ LL |     i
    = help: the trait `PartialEq<Bar<'b, 'a>>` is not implemented for `&i32`
    = help: the trait `PartialEq` is implemented for `i32`
 
-error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0})`
+error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
   --> $DIR/self-referential.rs:14:31
    |
 LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
-   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0})`
+   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
 LL |
 LL |     (42, i)
    |     ------- return type was inferred to be `(i32, &i32)` here
    |
-   = help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0})>` is not implemented for `&i32`
+   = help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)>` is not implemented for `&i32`
    = help: the trait `PartialEq` is implemented for `i32`
 
-error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
+error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
   --> $DIR/self-referential.rs:21:31
    |
 LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
-   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0})`
+   |                               ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
 LL |
 LL |     (42, i)
    |     ------- return type was inferred to be `(i32, &i32)` here
    |
-   = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0})>` is not implemented for `&i32`
+   = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)>` is not implemented for `&i32`
    = help: the trait `PartialEq` is implemented for `i32`
 
 error: aborting due to 3 previous errors
diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs
index eae5e5fdde2..457c4affb9d 100644
--- a/tests/ui/type-alias-impl-trait/variance.rs
+++ b/tests/ui/type-alias-impl-trait/variance.rs
@@ -5,21 +5,21 @@
 trait Captures<'a> {}
 impl<T> Captures<'_> for T {}
 
-type NotCapturedEarly<'a> = impl Sized; //~ [o]
+type NotCapturedEarly<'a> = impl Sized; //~ [*, o]
 //~^ ERROR: unconstrained opaque type
 
-type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o]
+type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o]
 //~^ ERROR: unconstrained opaque type
 
-// TAIT does *not* capture `'b`
-type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o]
-//~^ ERROR: unconstrained opaque type
+type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [*, o, o]
+//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
+//~| ERROR: unconstrained opaque type
 
-// TAIT does *not* capture `'b`
-type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [o]
-//~^ ERROR: unconstrained opaque type
+type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [*, o, o]
+//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
+//~| ERROR: unconstrained opaque type
 
-type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o]
+type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o]
 //~^ ERROR: unconstrained opaque type
 
 trait Foo<'i> {
@@ -31,24 +31,24 @@ trait Foo<'i> {
 }
 
 impl<'i> Foo<'i> for &'i () {
-    type ImplicitCapture<'a> = impl Sized; //~ [o, o]
+    type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
+    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
+    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 }
 
 impl<'i> Foo<'i> for () {
-    type ImplicitCapture<'a> = impl Sized; //~ [o, o]
+    type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
+    type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 
-    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
+    type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
     //~^ ERROR: unconstrained opaque type
 }
 
diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr
index 914541fcf66..eafe583e89c 100644
--- a/tests/ui/type-alias-impl-trait/variance.stderr
+++ b/tests/ui/type-alias-impl-trait/variance.stderr
@@ -1,3 +1,15 @@
+error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
+  --> $DIR/variance.rs:14:36
+   |
+LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
+   |                                    ^^
+
+error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
+  --> $DIR/variance.rs:18:29
+   |
+LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
+   |                             ^^
+
 error: unconstrained opaque type
   --> $DIR/variance.rs:8:29
    |
@@ -15,7 +27,7 @@ LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
    = note: `CapturedEarly` must be used in combination with a concrete type within the same module
 
 error: unconstrained opaque type
-  --> $DIR/variance.rs:15:56
+  --> $DIR/variance.rs:14:56
    |
 LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
    |                                                        ^^^^^^^^^^
@@ -23,7 +35,7 @@ LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
    = note: `NotCapturedLate` must be used in combination with a concrete type within the same module
 
 error: unconstrained opaque type
-  --> $DIR/variance.rs:19:49
+  --> $DIR/variance.rs:18:49
    |
 LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -86,71 +98,72 @@ LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |
    = note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl
 
-error: [o]
+error: [*, o]
   --> $DIR/variance.rs:8:29
    |
 LL | type NotCapturedEarly<'a> = impl Sized;
    |                             ^^^^^^^^^^
 
-error: [o]
+error: [*, o]
   --> $DIR/variance.rs:11:26
    |
 LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o]
-  --> $DIR/variance.rs:15:56
+error: [*, o, o]
+  --> $DIR/variance.rs:14:56
    |
 LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
    |                                                        ^^^^^^^^^^
 
-error: [o]
-  --> $DIR/variance.rs:19:49
+error: [*, o, o]
+  --> $DIR/variance.rs:18:49
    |
 LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o, o]
+error: [*, *, o, o, o]
   --> $DIR/variance.rs:22:27
    |
 LL | type Bar<'a, 'b: 'b, T> = impl Sized;
    |                           ^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:34:32
    |
 LL |     type ImplicitCapture<'a> = impl Sized;
    |                                ^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:37:42
    |
 LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:40:39
    |
 LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:45:32
    |
 LL |     type ImplicitCapture<'a> = impl Sized;
    |                                ^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:48:42
    |
 LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: [o, o]
+error: [*, *, o, o]
   --> $DIR/variance.rs:51:39
    |
 LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 22 previous errors
+error: aborting due to 24 previous errors
 
+For more information about this error, try `rustc --explain E0657`.