@@ -2570,7 +2570,54 @@ impl<'a> LoweringContext<'a> {
25702570
25712571 self . allocate_hir_id_counter ( opaque_ty_node_id) ;
25722572
2573+ // When we create the opaque type for this async fn, it is going to have
2574+ // to capture all the lifetimes involved in the signature (including in the
2575+ // return type). This is done by introducing lifetime parameters for:
2576+ //
2577+ // - all the explicitly declared lifetimes from the impl and function itself;
2578+ // - all the elided lifetimes in the fn arguments;
2579+ // - all the elided lifetimes in the return type.
2580+ //
2581+ // So for example in this snippet:
2582+ //
2583+ // ```rust
2584+ // impl<'a> Foo<'a> {
2585+ // async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
2586+ // // ^ '0 ^ '1 ^ '2
2587+ // // elided lifetimes used below
2588+ // }
2589+ // }
2590+ // ```
2591+ //
2592+ // we would create an opaque type like:
2593+ //
2594+ // ```
2595+ // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
2596+ // ```
2597+ //
2598+ // and we would then desugar `bar` to the equivalent of:
2599+ //
2600+ // ```rust
2601+ // impl<'a> Foo<'a> {
2602+ // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
2603+ // }
2604+ // ```
2605+ //
2606+ // Note that the final parameter to `Bar` is `'_`, not `'2` --
2607+ // this is because the elided lifetimes from the return type
2608+ // should be figured out using the ordinary elision rules, and
2609+ // this desugaring achieves that.
2610+ //
2611+ // The variable `input_lifetimes_count` tracks the number of
2612+ // lifetime parameters to the opaque type *not counting* those
2613+ // lifetimes elided in the return type. This includes those
2614+ // that are explicitly declared (`in_scope_lifetimes`) and
2615+ // those elided lifetimes we found in the arguments (current
2616+ // content of `lifetimes_to_define`). Next, we will process
2617+ // the return type, which will cause `lifetimes_to_define` to
2618+ // grow.
25732619 let input_lifetimes_count = self . in_scope_lifetimes . len ( ) + self . lifetimes_to_define . len ( ) ;
2620+
25742621 let ( opaque_ty_id, lifetime_params) = self . with_hir_id_owner ( opaque_ty_node_id, |this| {
25752622 // We have to be careful to get elision right here. The
25762623 // idea is that we create a lifetime parameter for each
@@ -2635,29 +2682,27 @@ impl<'a> LoweringContext<'a> {
26352682 ( opaque_ty_id, lifetime_params)
26362683 } ) ;
26372684
2638- // Create the generic lifetime arguments that we will supply
2639- // to the opaque return type. Consider:
2685+ // As documented above on the variable
2686+ // `input_lifetimes_count`, we need to create the lifetime
2687+ // arguments to our opaque type. Continuing with our example,
2688+ // we're creating the type arguments for the return type:
26402689 //
2641- // ```rust
2642- // async fn foo(x: &u32, ) -> &[&u32] { .. }
26432690 // ```
2644- //
2645- // Here, we would create something like:
2646- //
2647- // ```rust
2648- // type Foo<'a, 'b, 'c> = impl Future<Output = &'a [&'b u32]>;
2649- // fn foo<'a>(x: &'a u32) -> Foo<'a, '_, '_>
2691+ // Bar<'a, 'b, '0, '1, '_>
26502692 // ```
26512693 //
2652- // Note that for the lifetimes which came from the input
2653- // (`'a`, here), we supply them as arguments to the return
2654- // type `Foo`. But for those lifetime parameters (`'b`, `'c`)
2655- // that we created from the return type, we want to use `'_`
2656- // in the return type, so as to trigger elision.
2694+ // For the "input" lifetime parameters, we wish to create
2695+ // references to the parameters themselves, including the
2696+ // "implicit" ones created from parameter types (`'a`, `'b`,
2697+ // '`0`, `'1`).
2698+ //
2699+ // For the "output" lifetime parameters, we just want to
2700+ // generate `'_`.
26572701 let mut generic_args: Vec < _ > =
26582702 lifetime_params[ ..input_lifetimes_count]
26592703 . iter ( )
26602704 . map ( |& ( span, hir_name) | {
2705+ // Input lifetime like `'a` or `'1`:
26612706 GenericArg :: Lifetime ( hir:: Lifetime {
26622707 hir_id : self . next_id ( ) ,
26632708 span,
@@ -2669,6 +2714,7 @@ impl<'a> LoweringContext<'a> {
26692714 lifetime_params[ input_lifetimes_count..]
26702715 . iter ( )
26712716 . map ( |& ( span, _) | {
2717+ // Output lifetime like `'_`.
26722718 GenericArg :: Lifetime ( hir:: Lifetime {
26732719 hir_id : self . next_id ( ) ,
26742720 span,
0 commit comments