@@ -1659,12 +1659,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16591659
16601660 // When we create the opaque type for this async fn, it is going to have
16611661 // to capture all the lifetimes involved in the signature (including in the
1662- // return type). This is done by:
1662+ // return type). This is done by introducing lifetime parameters for :
16631663 //
1664- // - making the opaque type inherit all lifetime parameters from its parent;
1665- // - make all the elided lifetimes in the fn arguments into parameters;
1666- // - manually introducing parameters on the opaque type for elided
1667- // lifetimes in the return type.
1664+ // - all the explicitly declared lifetimes from the impl and function itself;
1665+ // - all the elided lifetimes in the fn arguments;
1666+ // - all the elided lifetimes in the return type.
16681667 //
16691668 // So for example in this snippet:
16701669 //
@@ -1680,22 +1679,44 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
16801679 // we would create an opaque type like:
16811680 //
16821681 // ```
1683- // type Foo <'a>::bar< 'b, '0, '1>::Bar< '2> = impl Future<Output = &'2 u32>;
1682+ // type Bar <'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
16841683 // ```
16851684 //
16861685 // and we would then desugar `bar` to the equivalent of:
16871686 //
16881687 // ```rust
16891688 // impl<'a> Foo<'a> {
1690- // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'_>
1689+ // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, ' _>
16911690 // }
16921691 // ```
16931692 //
16941693 // Note that the final parameter to `Bar` is `'_`, not `'2` --
16951694 // this is because the elided lifetimes from the return type
16961695 // should be figured out using the ordinary elision rules, and
16971696 // this desugaring achieves that.
1698- let mut lifetime_params = Vec :: new ( ) ;
1697+
1698+ debug ! ( "lower_async_fn_ret_ty: in_scope_lifetimes={:#?}" , self . in_scope_lifetimes) ;
1699+ debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , self . lifetimes_to_define) ;
1700+
1701+ // Calculate all the lifetimes that should be captured
1702+ // by the opaque type. This should include all in-scope
1703+ // lifetime parameters, including those defined in-band.
1704+ //
1705+ // `lifetime_params` is a vector of tuple (span, parameter name, lifetime name).
1706+
1707+ // Input lifetime like `'a` or `'1`:
1708+ let mut lifetime_params: Vec < _ > = self
1709+ . in_scope_lifetimes
1710+ . iter ( )
1711+ . cloned ( )
1712+ . map ( |name| ( name. ident ( ) . span , name, hir:: LifetimeName :: Param ( name) ) )
1713+ . chain (
1714+ self . lifetimes_to_define
1715+ . iter ( )
1716+ . map ( |& ( span, name) | ( span, name, hir:: LifetimeName :: Param ( name) ) ) ,
1717+ )
1718+ . collect ( ) ;
1719+
16991720 self . with_hir_id_owner ( opaque_ty_node_id, |this| {
17001721 // We have to be careful to get elision right here. The
17011722 // idea is that we create a lifetime parameter for each
@@ -1714,12 +1735,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17141735 debug ! ( "lower_async_fn_ret_ty: future_bound={:#?}" , future_bound) ;
17151736 debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , lifetimes_to_define) ;
17161737
1717- // Output lifetime like `'_`:
1718- lifetime_params = lifetimes_to_define;
1738+ lifetime_params. extend (
1739+ // Output lifetime like `'_`:
1740+ lifetimes_to_define
1741+ . into_iter ( )
1742+ . map ( |( span, name) | ( span, name, hir:: LifetimeName :: Implicit ( false ) ) ) ,
1743+ ) ;
17191744 debug ! ( "lower_async_fn_ret_ty: lifetime_params={:#?}" , lifetime_params) ;
17201745
17211746 let generic_params =
1722- this. arena . alloc_from_iter ( lifetime_params. iter ( ) . map ( |& ( span, hir_name) | {
1747+ this. arena . alloc_from_iter ( lifetime_params. iter ( ) . map ( |& ( span, hir_name, _ ) | {
17231748 this. lifetime_to_generic_param ( span, hir_name, opaque_ty_def_id)
17241749 } ) ) ;
17251750
@@ -1737,22 +1762,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17371762 this. generate_opaque_type ( opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
17381763 } ) ;
17391764
1740- // We need to create the lifetime arguments to our opaque type.
1741- // Continuing with our example, we're creating the type arguments
1742- // for the return type:
1765+ // As documented above on the variable
1766+ // `input_lifetimes_count`, we need to create the lifetime
1767+ // arguments to our opaque type. Continuing with our example,
1768+ // we're creating the type arguments for the return type:
17431769 //
17441770 // ```
1745- // For <'a>::bar< 'b, '0, '1>::Bar< '_>
1771+ // Bar <'a, 'b, '0, '1, '_>
17461772 // ```
17471773 //
1748- // For the "input" lifetime parameters are inherited automatically.
1749- // For the "output" lifetime parameters, we just want to generate `'_`.
1774+ // For the "input" lifetime parameters, we wish to create
1775+ // references to the parameters themselves, including the
1776+ // "implicit" ones created from parameter types (`'a`, `'b`,
1777+ // '`0`, `'1`).
1778+ //
1779+ // For the "output" lifetime parameters, we just want to
1780+ // generate `'_`.
17501781 let generic_args =
1751- self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, _) | {
1782+ self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, _, name ) | {
17521783 GenericArg :: Lifetime ( hir:: Lifetime {
17531784 hir_id : self . next_id ( ) ,
17541785 span : self . lower_span ( span) ,
1755- name : hir :: LifetimeName :: Implicit ( false ) ,
1786+ name,
17561787 } )
17571788 } ) ) ;
17581789
0 commit comments