@@ -1462,17 +1462,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14621462 // Contains the new lifetime definitions created for the TAIT (if any).
14631463 let mut collected_lifetimes = Vec :: new ( ) ;
14641464
1465- // If this came from a TAIT (as opposed to a function that returns an RPIT), we only want
1466- // to capture the lifetimes that appear in the bounds. So visit the bounds to find out
1467- // exactly which ones those are.
1468- let lifetimes_to_remap = if origin == hir:: OpaqueTyOrigin :: TyAlias {
1469- // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
1470- Vec :: new ( )
1471- } else {
1472- // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
1473- // we only keep the lifetimes that appear in the `impl Debug` itself:
1474- lifetime_collector:: lifetimes_in_bounds ( & self . resolver , bounds)
1475- } ;
1465+ // Contraty to the async case where only capture early-bound lifetimes, an trait bound in
1466+ // RPIT or TAIT may introduce late-bound lifetimes through HRTB.
1467+ // ```rust,ignore
1468+ // trait Foo<T> {};
1469+ // trait Bar<'a, 'b> {}
1470+ // fn baz<'a>() -> &'a dyn for<'b> Foo<impl Bar<'a, 'b>> {}
1471+ // ```
1472+ //
1473+ // In that case, we desugar lifetimes as:
1474+ // ```rust,ignore
1475+ // fn baz<'a>() -> &'a dyn for<'b> Foo<baz::<'a>::opaque::<'b>> {}
1476+ // opaque baz::<'a>::opaque<'b>: Bar<'a, 'b>;
1477+ // ```
1478+ //
1479+ // In that case, the lifetime `'a` is bound to an item, so `generics_of` will handle it.
1480+ // However, the lifetime `'b` is not bound to any item, so we need to create a special
1481+ // parameter on the opaque for it.
1482+ let lifetimes_to_remap = lifetime_collector:: lifetimes_in_bounds ( & self . resolver , bounds) ;
14761483 debug ! ( ?lifetimes_to_remap) ;
14771484
14781485 self . with_hir_id_owner ( opaque_ty_node_id, |lctx| {
0 commit comments