@@ -1462,17 +1462,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1462
1462
// Contains the new lifetime definitions created for the TAIT (if any).
1463
1463
let mut collected_lifetimes = Vec :: new ( ) ;
1464
1464
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) ;
1476
1483
debug ! ( ?lifetimes_to_remap) ;
1477
1484
1478
1485
self . with_hir_id_owner ( opaque_ty_node_id, |lctx| {
0 commit comments