@@ -649,15 +649,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
649649 & mut self ,
650650 f : impl FnOnce ( & mut Self ) -> T ,
651651 ) -> ( Vec < ( Span , ParamName ) > , T ) {
652- assert ! ( !self . is_collecting_in_band_lifetimes) ;
653- assert ! ( self . lifetimes_to_define. is_empty( ) ) ;
654- self . is_collecting_in_band_lifetimes = true ;
652+ let was_collecting = std:: mem:: replace ( & mut self . is_collecting_in_band_lifetimes , true ) ;
653+ let len = self . lifetimes_to_define . len ( ) ;
655654
656655 let res = f ( self ) ;
657656
658- self . is_collecting_in_band_lifetimes = false ;
659-
660- let lifetimes_to_define = std:: mem:: take ( & mut self . lifetimes_to_define ) ;
657+ let lifetimes_to_define = self . lifetimes_to_define . split_off ( len) ;
658+ self . is_collecting_in_band_lifetimes = was_collecting;
661659 ( lifetimes_to_define, res)
662660 }
663661
@@ -1689,18 +1687,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16891687 // this is because the elided lifetimes from the return type
16901688 // should be figured out using the ordinary elision rules, and
16911689 // this desugaring achieves that.
1690+
1691+ debug ! ( "lower_async_fn_ret_ty: in_scope_lifetimes={:#?}" , self . in_scope_lifetimes) ;
1692+ debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , self . lifetimes_to_define) ;
1693+
1694+ // Calculate all the lifetimes that should be captured
1695+ // by the opaque type. This should include all in-scope
1696+ // lifetime parameters, including those defined in-band.
16921697 //
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 ( ) ;
1698+ // `lifetime_params` is a vector of tuple (span, parameter name, lifetime name).
1699+
1700+ // Input lifetime like `'a` or `'1`:
1701+ let mut lifetime_params: Vec < _ > = self
1702+ . in_scope_lifetimes
1703+ . iter ( )
1704+ . cloned ( )
1705+ . map ( |name| ( name. ident ( ) . span , name, hir:: LifetimeName :: Param ( name) ) )
1706+ . chain (
1707+ self . lifetimes_to_define
1708+ . iter ( )
1709+ . map ( |& ( span, name) | ( span, name, hir:: LifetimeName :: Param ( name) ) ) ,
1710+ )
1711+ . collect ( ) ;
1712+
17041713 self . with_hir_id_owner ( opaque_ty_node_id, |this| {
17051714 // We have to be careful to get elision right here. The
17061715 // idea is that we create a lifetime parameter for each
@@ -1710,34 +1719,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17101719 //
17111720 // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
17121721 // 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)
1722+ let ( lifetimes_to_define, future_bound) =
1723+ this. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: CreateParameter , |this| {
1724+ this. collect_in_band_defs ( |this| {
1725+ this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
1726+ } )
17161727 } ) ;
1717-
17181728 debug ! ( "lower_async_fn_ret_ty: future_bound={:#?}" , future_bound) ;
1729+ debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , lifetimes_to_define) ;
17191730
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) ;
1731+ lifetime_params. extend (
1732+ // Output lifetime like `'_`:
1733+ lifetimes_to_define
1734+ . into_iter ( )
1735+ . map ( |( span, name) | ( span, name, hir:: LifetimeName :: Implicit ( false ) ) ) ,
1736+ ) ;
17361737 debug ! ( "lower_async_fn_ret_ty: lifetime_params={:#?}" , lifetime_params) ;
17371738
17381739 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)
1740+ this. arena . alloc_from_iter ( lifetime_params. iter ( ) . map ( |& ( span, hir_name, _ ) | {
1741+ this. lifetime_to_generic_param ( span, hir_name, opaque_ty_def_id)
17411742 } ) ) ;
17421743
17431744 let opaque_ty_item = hir:: OpaqueTy {
@@ -1771,25 +1772,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17711772 //
17721773 // For the "output" lifetime parameters, we just want to
17731774 // 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`:
1775+ let generic_args =
1776+ self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, _, name) | {
17781777 GenericArg :: Lifetime ( hir:: Lifetime {
17791778 hir_id : self . next_id ( ) ,
17801779 span : self . lower_span ( span) ,
1781- name : hir :: LifetimeName :: Param ( hir_name ) ,
1780+ name,
17821781 } )
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) ;
1782+ } ) ) ;
17931783
17941784 // Create the `Foo<...>` reference itself. Note that the `type
17951785 // Foo = impl Trait` is, internally, created as a child of the
0 commit comments