@@ -1399,7 +1399,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1399
1399
hir:: TyKind :: TraitObject ( bounds, lifetime_bound, * kind)
1400
1400
}
1401
1401
TyKind :: ImplTrait ( def_node_id, bounds, precise_capturing) => {
1402
- assert ! ( precise_capturing. is_none( ) , "precise captures not supported yet!" ) ;
1403
1402
let span = t. span ;
1404
1403
match itctx {
1405
1404
ImplTraitContext :: OpaqueTy { origin, fn_kind } => self . lower_opaque_impl_trait (
@@ -1409,8 +1408,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1409
1408
bounds,
1410
1409
fn_kind,
1411
1410
itctx,
1411
+ precise_capturing. as_deref ( ) ,
1412
1412
) ,
1413
1413
ImplTraitContext :: Universal => {
1414
+ assert ! (
1415
+ precise_capturing. is_none( ) ,
1416
+ "TODO: precise captures not supported on universals!"
1417
+ ) ;
1414
1418
let span = t. span ;
1415
1419
1416
1420
// HACK: pprust breaks strings with newlines when the type
@@ -1521,6 +1525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1521
1525
bounds : & GenericBounds ,
1522
1526
fn_kind : Option < FnDeclKind > ,
1523
1527
itctx : ImplTraitContext ,
1528
+ precise_capturing : Option < & ast:: GenericArgs > ,
1524
1529
) -> hir:: TyKind < ' hir > {
1525
1530
// Make sure we know that some funky desugaring has been going on here.
1526
1531
// This is a first: there is code in other places like for loop
@@ -1529,40 +1534,56 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1529
1534
// frequently opened issues show.
1530
1535
let opaque_ty_span = self . mark_span_with_reason ( DesugaringKind :: OpaqueTy , span, None ) ;
1531
1536
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.
1552
1557
self . resolver
1553
1558
. take_extra_lifetime_params ( opaque_ty_node_id)
1554
1559
. into_iter ( )
1555
1560
. map ( |( ident, id, _) | Lifetime { id, ident } )
1556
1561
. 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)
1562
1562
}
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
+ }
1566
1587
}
1567
1588
} ;
1568
1589
debug ! ( ?captured_lifetimes_to_duplicate) ;
0 commit comments