@@ -1659,12 +1659,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1659
1659
1660
1660
// When we create the opaque type for this async fn, it is going to have
1661
1661
// 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 :
1663
1663
//
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.
1668
1667
//
1669
1668
// So for example in this snippet:
1670
1669
//
@@ -1680,22 +1679,44 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1680
1679
// we would create an opaque type like:
1681
1680
//
1682
1681
// ```
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>;
1684
1683
// ```
1685
1684
//
1686
1685
// and we would then desugar `bar` to the equivalent of:
1687
1686
//
1688
1687
// ```rust
1689
1688
// 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, ' _>
1691
1690
// }
1692
1691
// ```
1693
1692
//
1694
1693
// Note that the final parameter to `Bar` is `'_`, not `'2` --
1695
1694
// this is because the elided lifetimes from the return type
1696
1695
// should be figured out using the ordinary elision rules, and
1697
1696
// 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
+
1699
1720
self . with_hir_id_owner ( opaque_ty_node_id, |this| {
1700
1721
// We have to be careful to get elision right here. The
1701
1722
// idea is that we create a lifetime parameter for each
@@ -1714,12 +1735,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1714
1735
debug ! ( "lower_async_fn_ret_ty: future_bound={:#?}" , future_bound) ;
1715
1736
debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , lifetimes_to_define) ;
1716
1737
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
+ ) ;
1719
1744
debug ! ( "lower_async_fn_ret_ty: lifetime_params={:#?}" , lifetime_params) ;
1720
1745
1721
1746
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, _ ) | {
1723
1748
this. lifetime_to_generic_param ( span, hir_name, opaque_ty_def_id)
1724
1749
} ) ) ;
1725
1750
@@ -1737,22 +1762,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1737
1762
this. generate_opaque_type ( opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1738
1763
} ) ;
1739
1764
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:
1743
1769
//
1744
1770
// ```
1745
- // For <'a>::bar< 'b, '0, '1>::Bar< '_>
1771
+ // Bar <'a, 'b, '0, '1, '_>
1746
1772
// ```
1747
1773
//
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 `'_`.
1750
1781
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 ) | {
1752
1783
GenericArg :: Lifetime ( hir:: Lifetime {
1753
1784
hir_id : self . next_id ( ) ,
1754
1785
span : self . lower_span ( span) ,
1755
- name : hir :: LifetimeName :: Implicit ( false ) ,
1786
+ name,
1756
1787
} )
1757
1788
} ) ) ;
1758
1789
0 commit comments