@@ -1399,7 +1399,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13991399 hir:: TyKind :: TraitObject ( bounds, lifetime_bound, * kind)
14001400 }
14011401 TyKind :: ImplTrait ( def_node_id, bounds, precise_capturing) => {
1402- assert ! ( precise_capturing. is_none( ) , "precise captures not supported yet!" ) ;
14031402 let span = t. span ;
14041403 match itctx {
14051404 ImplTraitContext :: OpaqueTy { origin, fn_kind } => self . lower_opaque_impl_trait (
@@ -1409,8 +1408,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14091408 bounds,
14101409 fn_kind,
14111410 itctx,
1411+ precise_capturing. as_deref ( ) ,
14121412 ) ,
14131413 ImplTraitContext :: Universal => {
1414+ assert ! (
1415+ precise_capturing. is_none( ) ,
1416+ "TODO: precise captures not supported on universals!"
1417+ ) ;
14141418 let span = t. span ;
14151419
14161420 // HACK: pprust breaks strings with newlines when the type
@@ -1521,6 +1525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15211525 bounds : & GenericBounds ,
15221526 fn_kind : Option < FnDeclKind > ,
15231527 itctx : ImplTraitContext ,
1528+ precise_capturing : Option < & ast:: GenericArgs > ,
15241529 ) -> hir:: TyKind < ' hir > {
15251530 // Make sure we know that some funky desugaring has been going on here.
15261531 // This is a first: there is code in other places like for loop
@@ -1529,40 +1534,56 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15291534 // frequently opened issues show.
15301535 let opaque_ty_span = self . mark_span_with_reason ( DesugaringKind :: OpaqueTy , span, None ) ;
15311536
1532- let captured_lifetimes_to_duplicate = match origin {
1533- hir :: OpaqueTyOrigin :: TyAlias { .. } => {
1534- // type alias impl trait and associated type position impl trait were
1535- // decided to capture all in-scope lifetimes, which we collect for
1536- // all opaques during resolution.
1537- self . resolver
1538- . take_extra_lifetime_params ( opaque_ty_node_id )
1539- . into_iter ( )
1540- . map ( | ( ident , id , _ ) | Lifetime { id , ident } )
1541- . collect ( )
1542- }
1543- hir :: OpaqueTyOrigin :: FnReturn ( .. ) => {
1544- if matches ! (
1545- fn_kind . expect ( "expected RPITs to be lowered with a FnKind" ) ,
1546- FnDeclKind :: Impl | FnDeclKind :: Trait
1547- ) || self . tcx . features ( ) . lifetime_capture_rules_2024
1548- || span . at_least_rust_2024 ( )
1549- {
1550- // return-position impl trait in trait was decided to capture all
1551- // in-scope lifetimes, which we collect for all opaques during resolution.
1537+ let captured_lifetimes_to_duplicate = if let Some ( precise_capturing ) = precise_capturing {
1538+ let ast :: GenericArgs :: AngleBracketed ( precise_capturing ) = precise_capturing else {
1539+ panic ! ( "we only parse angle-bracketed args" )
1540+ } ;
1541+ // We'll actually validate these later on; all we need is the list of
1542+ // lifetimes to duplicate during this portion of lowering.
1543+ precise_capturing
1544+ . args
1545+ . iter ( )
1546+ . filter_map ( |arg| match arg {
1547+ ast :: AngleBracketedArg :: Arg ( ast :: GenericArg :: Lifetime ( lt ) ) => Some ( * lt ) ,
1548+ _ => None ,
1549+ } )
1550+ . collect ( )
1551+ } else {
1552+ match origin {
1553+ hir :: OpaqueTyOrigin :: TyAlias { .. } => {
1554+ // type alias impl trait and associated type position impl trait were
1555+ // decided to capture all in-scope lifetimes, which we collect for
1556+ // all opaques during resolution.
15521557 self . resolver
15531558 . take_extra_lifetime_params ( opaque_ty_node_id)
15541559 . into_iter ( )
15551560 . map ( |( ident, id, _) | Lifetime { id, ident } )
15561561 . collect ( )
1557- } else {
1558- // in fn return position, like the `fn test<'a>() -> impl Debug + 'a`
1559- // example, we only need to duplicate lifetimes that appear in the
1560- // bounds, since those are the only ones that are captured by the opaque.
1561- lifetime_collector:: lifetimes_in_bounds ( self . resolver , bounds)
15621562 }
1563- }
1564- hir:: OpaqueTyOrigin :: AsyncFn ( ..) => {
1565- unreachable ! ( "should be using `lower_async_fn_ret_ty`" )
1563+ hir:: OpaqueTyOrigin :: FnReturn ( ..) => {
1564+ if matches ! (
1565+ fn_kind. expect( "expected RPITs to be lowered with a FnKind" ) ,
1566+ FnDeclKind :: Impl | FnDeclKind :: Trait
1567+ ) || self . tcx . features ( ) . lifetime_capture_rules_2024
1568+ || span. at_least_rust_2024 ( )
1569+ {
1570+ // return-position impl trait in trait was decided to capture all
1571+ // in-scope lifetimes, which we collect for all opaques during resolution.
1572+ self . resolver
1573+ . take_extra_lifetime_params ( opaque_ty_node_id)
1574+ . into_iter ( )
1575+ . map ( |( ident, id, _) | Lifetime { id, ident } )
1576+ . collect ( )
1577+ } else {
1578+ // in fn return position, like the `fn test<'a>() -> impl Debug + 'a`
1579+ // example, we only need to duplicate lifetimes that appear in the
1580+ // bounds, since those are the only ones that are captured by the opaque.
1581+ lifetime_collector:: lifetimes_in_bounds ( self . resolver , bounds)
1582+ }
1583+ }
1584+ hir:: OpaqueTyOrigin :: AsyncFn ( ..) => {
1585+ unreachable ! ( "should be using `lower_async_fn_ret_ty`" )
1586+ }
15661587 }
15671588 } ;
15681589 debug ! ( ?captured_lifetimes_to_duplicate) ;
0 commit comments