Skip to content

Commit 948739f

Browse files
committed
revamp comment
1 parent 03e7b96 commit 948739f

File tree

1 file changed

+61
-15
lines changed

1 file changed

+61
-15
lines changed

src/librustc/hir/lowering.rs

+61-15
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)