@@ -228,7 +228,7 @@ enum ImplTraitContext<'b, 'a> {
228
228
ReturnPositionOpaqueTy {
229
229
/// `DefId` for the parent function, used to look up necessary
230
230
/// information later.
231
- fn_def_id : DefId ,
231
+ fn_def_id : LocalDefId ,
232
232
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
233
233
origin : hir:: OpaqueTyOrigin ,
234
234
} ,
@@ -646,31 +646,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
646
646
/// parameter while `f` is running (and restored afterwards).
647
647
fn collect_in_band_defs < T > (
648
648
& mut self ,
649
- parent_def_id : LocalDefId ,
650
- anonymous_lifetime_mode : AnonymousLifetimeMode ,
651
- f : impl FnOnce ( & mut Self ) -> ( Vec < hir:: GenericParam < ' hir > > , T ) ,
652
- ) -> ( Vec < hir:: GenericParam < ' hir > > , T ) {
653
- assert ! ( !self . is_collecting_in_band_lifetimes) ;
654
- assert ! ( self . lifetimes_to_define. is_empty( ) ) ;
655
- let old_anonymous_lifetime_mode = self . anonymous_lifetime_mode ;
656
-
657
- self . anonymous_lifetime_mode = anonymous_lifetime_mode;
658
- self . is_collecting_in_band_lifetimes = true ;
659
-
660
- let ( in_band_ty_params, res) = f ( self ) ;
661
-
662
- self . is_collecting_in_band_lifetimes = false ;
663
- self . anonymous_lifetime_mode = old_anonymous_lifetime_mode;
664
-
665
- let lifetimes_to_define = self . lifetimes_to_define . split_off ( 0 ) ;
649
+ f : impl FnOnce ( & mut Self ) -> T ,
650
+ ) -> ( Vec < ( Span , ParamName ) > , T ) {
651
+ let was_collecting = std:: mem:: replace ( & mut self . is_collecting_in_band_lifetimes , true ) ;
652
+ let len = self . lifetimes_to_define . len ( ) ;
666
653
667
- let params = lifetimes_to_define
668
- . into_iter ( )
669
- . map ( |( span, hir_name) | self . lifetime_to_generic_param ( span, hir_name, parent_def_id) )
670
- . chain ( in_band_ty_params. into_iter ( ) )
671
- . collect ( ) ;
654
+ let res = f ( self ) ;
672
655
673
- ( params, res)
656
+ let lifetimes_to_define = self . lifetimes_to_define . split_off ( len) ;
657
+ self . is_collecting_in_band_lifetimes = was_collecting;
658
+ ( lifetimes_to_define, res)
674
659
}
675
660
676
661
/// Converts a lifetime into a new generic parameter.
@@ -785,27 +770,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
785
770
anonymous_lifetime_mode : AnonymousLifetimeMode ,
786
771
f : impl FnOnce ( & mut Self , & mut Vec < hir:: GenericParam < ' hir > > ) -> T ,
787
772
) -> ( hir:: Generics < ' hir > , T ) {
788
- let ( in_band_defs, ( mut lowered_generics, res) ) =
789
- self . with_in_scope_lifetime_defs ( & generics. params , |this| {
790
- this. collect_in_band_defs ( parent_def_id, anonymous_lifetime_mode, |this| {
791
- let mut params = Vec :: new ( ) ;
792
- // Note: it is necessary to lower generics *before* calling `f`.
793
- // When lowering `async fn`, there's a final step when lowering
794
- // the return type that assumes that all in-scope lifetimes have
795
- // already been added to either `in_scope_lifetimes` or
796
- // `lifetimes_to_define`. If we swapped the order of these two,
797
- // in-band-lifetimes introduced by generics or where-clauses
798
- // wouldn't have been added yet.
799
- let generics = this. lower_generics_mut (
800
- generics,
801
- ImplTraitContext :: Universal ( & mut params, this. current_hir_id_owner ) ,
802
- ) ;
803
- let res = f ( this, & mut params) ;
804
- ( params, ( generics, res) )
773
+ let ( lifetimes_to_define, ( mut lowered_generics, impl_trait_defs, res) ) = self
774
+ . collect_in_band_defs ( |this| {
775
+ this. with_anonymous_lifetime_mode ( anonymous_lifetime_mode, |this| {
776
+ this. with_in_scope_lifetime_defs ( & generics. params , |this| {
777
+ let mut impl_trait_defs = Vec :: new ( ) ;
778
+ // Note: it is necessary to lower generics *before* calling `f`.
779
+ // When lowering `async fn`, there's a final step when lowering
780
+ // the return type that assumes that all in-scope lifetimes have
781
+ // already been added to either `in_scope_lifetimes` or
782
+ // `lifetimes_to_define`. If we swapped the order of these two,
783
+ // in-band-lifetimes introduced by generics or where-clauses
784
+ // wouldn't have been added yet.
785
+ let generics = this. lower_generics_mut (
786
+ generics,
787
+ ImplTraitContext :: Universal (
788
+ & mut impl_trait_defs,
789
+ this. current_hir_id_owner ,
790
+ ) ,
791
+ ) ;
792
+ let res = f ( this, & mut impl_trait_defs) ;
793
+ ( generics, impl_trait_defs, res)
794
+ } )
805
795
} )
806
796
} ) ;
807
797
808
- lowered_generics. params . extend ( in_band_defs) ;
798
+ lowered_generics. params . extend (
799
+ lifetimes_to_define
800
+ . into_iter ( )
801
+ . map ( |( span, hir_name) | {
802
+ self . lifetime_to_generic_param ( span, hir_name, parent_def_id)
803
+ } )
804
+ . chain ( impl_trait_defs) ,
805
+ ) ;
809
806
810
807
let lowered_generics = lowered_generics. into_generics ( self . arena ) ;
811
808
( lowered_generics, res)
@@ -1380,7 +1377,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1380
1377
fn lower_opaque_impl_trait (
1381
1378
& mut self ,
1382
1379
span : Span ,
1383
- fn_def_id : Option < DefId > ,
1380
+ fn_def_id : Option < LocalDefId > ,
1384
1381
origin : hir:: OpaqueTyOrigin ,
1385
1382
opaque_ty_node_id : NodeId ,
1386
1383
capturable_lifetimes : Option < & FxHashSet < hir:: LifetimeName > > ,
@@ -1452,7 +1449,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1452
1449
span : lctx. lower_span ( span) ,
1453
1450
} ,
1454
1451
bounds : hir_bounds,
1455
- impl_trait_fn : fn_def_id,
1456
1452
origin,
1457
1453
} ;
1458
1454
@@ -1522,7 +1518,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1522
1518
fn lower_fn_decl (
1523
1519
& mut self ,
1524
1520
decl : & FnDecl ,
1525
- mut in_band_ty_params : Option < ( DefId , & mut Vec < hir:: GenericParam < ' hir > > ) > ,
1521
+ mut in_band_ty_params : Option < ( LocalDefId , & mut Vec < hir:: GenericParam < ' hir > > ) > ,
1526
1522
impl_trait_return_allow : bool ,
1527
1523
make_ret_async : Option < NodeId > ,
1528
1524
) -> & ' hir hir:: FnDecl < ' hir > {
@@ -1580,7 +1576,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1580
1576
Some ( ( def_id, _) ) if impl_trait_return_allow => {
1581
1577
ImplTraitContext :: ReturnPositionOpaqueTy {
1582
1578
fn_def_id : def_id,
1583
- origin : hir:: OpaqueTyOrigin :: FnReturn ,
1579
+ origin : hir:: OpaqueTyOrigin :: FnReturn ( def_id ) ,
1584
1580
}
1585
1581
}
1586
1582
_ => ImplTraitContext :: disallowed ( ) ,
@@ -1635,7 +1631,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1635
1631
fn lower_async_fn_ret_ty (
1636
1632
& mut self ,
1637
1633
output : & FnRetTy ,
1638
- fn_def_id : DefId ,
1634
+ fn_def_id : LocalDefId ,
1639
1635
opaque_ty_node_id : NodeId ,
1640
1636
) -> hir:: FnRetTy < ' hir > {
1641
1637
debug ! (
@@ -1689,18 +1685,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1689
1685
// this is because the elided lifetimes from the return type
1690
1686
// should be figured out using the ordinary elision rules, and
1691
1687
// this desugaring achieves that.
1688
+
1689
+ debug ! ( "lower_async_fn_ret_ty: in_scope_lifetimes={:#?}" , self . in_scope_lifetimes) ;
1690
+ debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , self . lifetimes_to_define) ;
1691
+
1692
+ // Calculate all the lifetimes that should be captured
1693
+ // by the opaque type. This should include all in-scope
1694
+ // lifetime parameters, including those defined in-band.
1692
1695
//
1693
- // The variable `input_lifetimes_count` tracks the number of
1694
- // lifetime parameters to the opaque type *not counting* those
1695
- // lifetimes elided in the return type. This includes those
1696
- // that are explicitly declared (`in_scope_lifetimes`) and
1697
- // those elided lifetimes we found in the arguments (current
1698
- // content of `lifetimes_to_define`). Next, we will process
1699
- // the return type, which will cause `lifetimes_to_define` to
1700
- // grow.
1701
- let input_lifetimes_count = self . in_scope_lifetimes . len ( ) + self . lifetimes_to_define . len ( ) ;
1702
-
1703
- let mut lifetime_params = Vec :: new ( ) ;
1696
+ // `lifetime_params` is a vector of tuple (span, parameter name, lifetime name).
1697
+
1698
+ // Input lifetime like `'a` or `'1`:
1699
+ let mut lifetime_params: Vec < _ > = self
1700
+ . in_scope_lifetimes
1701
+ . iter ( )
1702
+ . cloned ( )
1703
+ . map ( |name| ( name. ident ( ) . span , name, hir:: LifetimeName :: Param ( name) ) )
1704
+ . chain (
1705
+ self . lifetimes_to_define
1706
+ . iter ( )
1707
+ . map ( |& ( span, name) | ( span, name, hir:: LifetimeName :: Param ( name) ) ) ,
1708
+ )
1709
+ . collect ( ) ;
1710
+
1704
1711
self . with_hir_id_owner ( opaque_ty_node_id, |this| {
1705
1712
// We have to be careful to get elision right here. The
1706
1713
// idea is that we create a lifetime parameter for each
@@ -1710,34 +1717,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1710
1717
//
1711
1718
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1712
1719
// hence the elision takes place at the fn site.
1713
- let future_bound = this
1714
- . with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: CreateParameter , |this| {
1715
- this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
1720
+ let ( lifetimes_to_define, future_bound) =
1721
+ this. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: CreateParameter , |this| {
1722
+ this. collect_in_band_defs ( |this| {
1723
+ this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
1724
+ } )
1716
1725
} ) ;
1717
-
1718
1726
debug ! ( "lower_async_fn_ret_ty: future_bound={:#?}" , future_bound) ;
1727
+ debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , lifetimes_to_define) ;
1719
1728
1720
- // Calculate all the lifetimes that should be captured
1721
- // by the opaque type. This should include all in-scope
1722
- // lifetime parameters, including those defined in-band.
1723
- //
1724
- // Note: this must be done after lowering the output type,
1725
- // as the output type may introduce new in-band lifetimes.
1726
- lifetime_params = this
1727
- . in_scope_lifetimes
1728
- . iter ( )
1729
- . cloned ( )
1730
- . map ( |name| ( name. ident ( ) . span , name) )
1731
- . chain ( this. lifetimes_to_define . iter ( ) . cloned ( ) )
1732
- . collect ( ) ;
1733
-
1734
- debug ! ( "lower_async_fn_ret_ty: in_scope_lifetimes={:#?}" , this. in_scope_lifetimes) ;
1735
- debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , this. lifetimes_to_define) ;
1729
+ lifetime_params. extend (
1730
+ // Output lifetime like `'_`:
1731
+ lifetimes_to_define
1732
+ . into_iter ( )
1733
+ . map ( |( span, name) | ( span, name, hir:: LifetimeName :: Implicit ( false ) ) ) ,
1734
+ ) ;
1736
1735
debug ! ( "lower_async_fn_ret_ty: lifetime_params={:#?}" , lifetime_params) ;
1737
1736
1738
1737
let generic_params =
1739
- this. arena . alloc_from_iter ( lifetime_params. iter ( ) . map ( |( span, hir_name) | {
1740
- this. lifetime_to_generic_param ( * span, * hir_name, opaque_ty_def_id)
1738
+ this. arena . alloc_from_iter ( lifetime_params. iter ( ) . map ( |& ( span, hir_name, _ ) | {
1739
+ this. lifetime_to_generic_param ( span, hir_name, opaque_ty_def_id)
1741
1740
} ) ) ;
1742
1741
1743
1742
let opaque_ty_item = hir:: OpaqueTy {
@@ -1747,8 +1746,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1747
1746
span : this. lower_span ( span) ,
1748
1747
} ,
1749
1748
bounds : arena_vec ! [ this; future_bound] ,
1750
- impl_trait_fn : Some ( fn_def_id) ,
1751
- origin : hir:: OpaqueTyOrigin :: AsyncFn ,
1749
+ origin : hir:: OpaqueTyOrigin :: AsyncFn ( fn_def_id) ,
1752
1750
} ;
1753
1751
1754
1752
trace ! ( "exist ty from async fn def id: {:#?}" , opaque_ty_def_id) ;
@@ -1771,25 +1769,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1771
1769
//
1772
1770
// For the "output" lifetime parameters, we just want to
1773
1771
// generate `'_`.
1774
- let mut generic_args = Vec :: with_capacity ( lifetime_params. len ( ) ) ;
1775
- generic_args. extend ( lifetime_params[ ..input_lifetimes_count] . iter ( ) . map (
1776
- |& ( span, hir_name) | {
1777
- // Input lifetime like `'a` or `'1`:
1772
+ let generic_args =
1773
+ self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, _, name) | {
1778
1774
GenericArg :: Lifetime ( hir:: Lifetime {
1779
1775
hir_id : self . next_id ( ) ,
1780
1776
span : self . lower_span ( span) ,
1781
- name : hir :: LifetimeName :: Param ( hir_name ) ,
1777
+ name,
1782
1778
} )
1783
- } ,
1784
- ) ) ;
1785
- generic_args. extend ( lifetime_params[ input_lifetimes_count..] . iter ( ) . map ( |& ( span, _) |
1786
- // Output lifetime like `'_`.
1787
- GenericArg :: Lifetime ( hir:: Lifetime {
1788
- hir_id : self . next_id ( ) ,
1789
- span : self . lower_span ( span) ,
1790
- name : hir:: LifetimeName :: Implicit ( false ) ,
1791
- } ) ) ) ;
1792
- let generic_args = self . arena . alloc_from_iter ( generic_args) ;
1779
+ } ) ) ;
1793
1780
1794
1781
// Create the `Foo<...>` reference itself. Note that the `type
1795
1782
// Foo = impl Trait` is, internally, created as a child of the
@@ -1805,7 +1792,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1805
1792
fn lower_async_fn_output_type_to_future_bound (
1806
1793
& mut self ,
1807
1794
output : & FnRetTy ,
1808
- fn_def_id : DefId ,
1795
+ fn_def_id : LocalDefId ,
1809
1796
span : Span ,
1810
1797
) -> hir:: GenericBound < ' hir > {
1811
1798
// Compute the `T` in `Future<Output = T>` from the return type.
@@ -1816,7 +1803,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1816
1803
// generates.
1817
1804
let context = ImplTraitContext :: ReturnPositionOpaqueTy {
1818
1805
fn_def_id,
1819
- origin : hir:: OpaqueTyOrigin :: FnReturn ,
1806
+ origin : hir:: OpaqueTyOrigin :: FnReturn ( fn_def_id ) ,
1820
1807
} ;
1821
1808
self . lower_ty ( ty, context)
1822
1809
}
@@ -2453,17 +2440,12 @@ impl<'hir> GenericArgsCtor<'hir> {
2453
2440
}
2454
2441
}
2455
2442
2443
+ #[ tracing:: instrument( level = "debug" ) ]
2456
2444
fn lifetimes_from_impl_trait_bounds (
2457
2445
opaque_ty_id : NodeId ,
2458
2446
bounds : hir:: GenericBounds < ' _ > ,
2459
2447
lifetimes_to_include : Option < & FxHashSet < hir:: LifetimeName > > ,
2460
2448
) -> Vec < ( hir:: LifetimeName , Span ) > {
2461
- debug ! (
2462
- "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
2463
- bounds={:#?})",
2464
- opaque_ty_id, bounds,
2465
- ) ;
2466
-
2467
2449
// This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
2468
2450
// appear in the bounds, excluding lifetimes that are created within the bounds.
2469
2451
// E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
0 commit comments