@@ -648,15 +648,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
648
648
& mut self ,
649
649
f : impl FnOnce ( & mut Self ) -> T ,
650
650
) -> ( Vec < ( Span , ParamName ) > , T ) {
651
- assert ! ( !self . is_collecting_in_band_lifetimes) ;
652
- assert ! ( self . lifetimes_to_define. is_empty( ) ) ;
653
- self . is_collecting_in_band_lifetimes = true ;
651
+ let was_collecting = std:: mem:: replace ( & mut self . is_collecting_in_band_lifetimes , true ) ;
652
+ let len = self . lifetimes_to_define . len ( ) ;
654
653
655
654
let res = f ( self ) ;
656
655
657
- self . is_collecting_in_band_lifetimes = false ;
658
-
659
- let lifetimes_to_define = std:: mem:: take ( & mut self . lifetimes_to_define ) ;
656
+ let lifetimes_to_define = self . lifetimes_to_define . split_off ( len) ;
657
+ self . is_collecting_in_band_lifetimes = was_collecting;
660
658
( lifetimes_to_define, res)
661
659
}
662
660
@@ -1688,18 +1686,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1688
1686
// this is because the elided lifetimes from the return type
1689
1687
// should be figured out using the ordinary elision rules, and
1690
1688
// this desugaring achieves that.
1689
+
1690
+ debug ! ( "lower_async_fn_ret_ty: in_scope_lifetimes={:#?}" , self . in_scope_lifetimes) ;
1691
+ debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , self . lifetimes_to_define) ;
1692
+
1693
+ // Calculate all the lifetimes that should be captured
1694
+ // by the opaque type. This should include all in-scope
1695
+ // lifetime parameters, including those defined in-band.
1691
1696
//
1692
- // The variable `input_lifetimes_count` tracks the number of
1693
- // lifetime parameters to the opaque type *not counting* those
1694
- // lifetimes elided in the return type. This includes those
1695
- // that are explicitly declared (`in_scope_lifetimes`) and
1696
- // those elided lifetimes we found in the arguments (current
1697
- // content of `lifetimes_to_define`). Next, we will process
1698
- // the return type, which will cause `lifetimes_to_define` to
1699
- // grow.
1700
- let input_lifetimes_count = self . in_scope_lifetimes . len ( ) + self . lifetimes_to_define . len ( ) ;
1701
-
1702
- let mut lifetime_params = Vec :: new ( ) ;
1697
+ // `lifetime_params` is a vector of tuple (span, parameter name, lifetime name).
1698
+
1699
+ // Input lifetime like `'a` or `'1`:
1700
+ let mut lifetime_params: Vec < _ > = self
1701
+ . in_scope_lifetimes
1702
+ . iter ( )
1703
+ . cloned ( )
1704
+ . map ( |name| ( name. ident ( ) . span , name, hir:: LifetimeName :: Param ( name) ) )
1705
+ . chain (
1706
+ self . lifetimes_to_define
1707
+ . iter ( )
1708
+ . map ( |& ( span, name) | ( span, name, hir:: LifetimeName :: Param ( name) ) ) ,
1709
+ )
1710
+ . collect ( ) ;
1711
+
1703
1712
self . with_hir_id_owner ( opaque_ty_node_id, |this| {
1704
1713
// We have to be careful to get elision right here. The
1705
1714
// idea is that we create a lifetime parameter for each
@@ -1709,34 +1718,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1709
1718
//
1710
1719
// Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1711
1720
// hence the elision takes place at the fn site.
1712
- let future_bound = this
1713
- . with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: CreateParameter , |this| {
1714
- this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
1721
+ let ( lifetimes_to_define, future_bound) =
1722
+ this. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: CreateParameter , |this| {
1723
+ this. collect_in_band_defs ( |this| {
1724
+ this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
1725
+ } )
1715
1726
} ) ;
1716
-
1717
1727
debug ! ( "lower_async_fn_ret_ty: future_bound={:#?}" , future_bound) ;
1728
+ debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , lifetimes_to_define) ;
1718
1729
1719
- // Calculate all the lifetimes that should be captured
1720
- // by the opaque type. This should include all in-scope
1721
- // lifetime parameters, including those defined in-band.
1722
- //
1723
- // Note: this must be done after lowering the output type,
1724
- // as the output type may introduce new in-band lifetimes.
1725
- lifetime_params = this
1726
- . in_scope_lifetimes
1727
- . iter ( )
1728
- . cloned ( )
1729
- . map ( |name| ( name. ident ( ) . span , name) )
1730
- . chain ( this. lifetimes_to_define . iter ( ) . cloned ( ) )
1731
- . collect ( ) ;
1732
-
1733
- debug ! ( "lower_async_fn_ret_ty: in_scope_lifetimes={:#?}" , this. in_scope_lifetimes) ;
1734
- debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , this. lifetimes_to_define) ;
1730
+ lifetime_params. extend (
1731
+ // Output lifetime like `'_`:
1732
+ lifetimes_to_define
1733
+ . into_iter ( )
1734
+ . map ( |( span, name) | ( span, name, hir:: LifetimeName :: Implicit ( false ) ) ) ,
1735
+ ) ;
1735
1736
debug ! ( "lower_async_fn_ret_ty: lifetime_params={:#?}" , lifetime_params) ;
1736
1737
1737
1738
let generic_params =
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)
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)
1740
1741
} ) ) ;
1741
1742
1742
1743
let opaque_ty_item = hir:: OpaqueTy {
@@ -1770,25 +1771,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1770
1771
//
1771
1772
// For the "output" lifetime parameters, we just want to
1772
1773
// generate `'_`.
1773
- let mut generic_args = Vec :: with_capacity ( lifetime_params. len ( ) ) ;
1774
- generic_args. extend ( lifetime_params[ ..input_lifetimes_count] . iter ( ) . map (
1775
- |& ( span, hir_name) | {
1776
- // Input lifetime like `'a` or `'1`:
1774
+ let generic_args =
1775
+ self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, _, name) | {
1777
1776
GenericArg :: Lifetime ( hir:: Lifetime {
1778
1777
hir_id : self . next_id ( ) ,
1779
1778
span : self . lower_span ( span) ,
1780
- name : hir :: LifetimeName :: Param ( hir_name ) ,
1779
+ name,
1781
1780
} )
1782
- } ,
1783
- ) ) ;
1784
- generic_args. extend ( lifetime_params[ input_lifetimes_count..] . iter ( ) . map ( |& ( span, _) |
1785
- // Output lifetime like `'_`.
1786
- GenericArg :: Lifetime ( hir:: Lifetime {
1787
- hir_id : self . next_id ( ) ,
1788
- span : self . lower_span ( span) ,
1789
- name : hir:: LifetimeName :: Implicit ( false ) ,
1790
- } ) ) ) ;
1791
- let generic_args = self . arena . alloc_from_iter ( generic_args) ;
1781
+ } ) ) ;
1792
1782
1793
1783
// Create the `Foo<...>` reference itself. Note that the `type
1794
1784
// Foo = impl Trait` is, internally, created as a child of the
0 commit comments