@@ -341,49 +341,6 @@ enum AnonymousLifetimeMode {
341
341
342
342
/// Pass responsibility to `resolve_lifetime` code for all cases.
343
343
PassThrough ,
344
-
345
- /// Used in the return types of `async fn` where there exists
346
- /// exactly one argument-position elided lifetime.
347
- ///
348
- /// In `async fn`, we lower the arguments types using the `CreateParameter`
349
- /// mode, meaning that non-`dyn` elided lifetimes are assigned a fresh name.
350
- /// If any corresponding elided lifetimes appear in the output, we need to
351
- /// replace them with references to the fresh name assigned to the corresponding
352
- /// elided lifetime in the arguments.
353
- ///
354
- /// For **Modern cases**, replace the anonymous parameter with a
355
- /// reference to a specific freshly-named lifetime that was
356
- /// introduced in argument
357
- ///
358
- /// For **Dyn Bound** cases, pass responsibility to
359
- /// `resole_lifetime` code.
360
- Replace ( LtReplacement ) ,
361
- }
362
-
363
- /// The type of elided lifetime replacement to perform on `async fn` return types.
364
- #[ derive( Copy , Clone ) ]
365
- enum LtReplacement {
366
- /// Fresh name introduced by the single non-dyn elided lifetime
367
- /// in the arguments of the async fn.
368
- Some ( ParamName ) ,
369
-
370
- /// There is no single non-dyn elided lifetime because no lifetimes
371
- /// appeared in the arguments.
372
- NoLifetimes ,
373
-
374
- /// There is no single non-dyn elided lifetime because multiple
375
- /// lifetimes appeared in the arguments.
376
- MultipleLifetimes ,
377
- }
378
-
379
- /// Calculates the `LtReplacement` to use for elided lifetimes in the return
380
- /// type based on the fresh elided lifetimes introduced in argument position.
381
- fn get_elided_lt_replacement ( arg_position_lifetimes : & [ ( Span , ParamName ) ] ) -> LtReplacement {
382
- match arg_position_lifetimes {
383
- [ ] => LtReplacement :: NoLifetimes ,
384
- [ ( _span, param) ] => LtReplacement :: Some ( * param) ,
385
- _ => LtReplacement :: MultipleLifetimes ,
386
- }
387
344
}
388
345
389
346
struct ImplTraitTypeIdVisitor < ' a > { ids : & ' a mut SmallVec < [ NodeId ; 1 ] > }
@@ -2318,8 +2275,7 @@ impl<'a> LoweringContext<'a> {
2318
2275
err. emit ( ) ;
2319
2276
}
2320
2277
AnonymousLifetimeMode :: PassThrough |
2321
- AnonymousLifetimeMode :: ReportError |
2322
- AnonymousLifetimeMode :: Replace ( _) => {
2278
+ AnonymousLifetimeMode :: ReportError => {
2323
2279
self . sess . buffer_lint_with_diagnostic (
2324
2280
ELIDED_LIFETIMES_IN_PATHS ,
2325
2281
CRATE_NODE_ID ,
@@ -2515,7 +2471,6 @@ impl<'a> LoweringContext<'a> {
2515
2471
2516
2472
// Remember how many lifetimes were already around so that we can
2517
2473
// only look at the lifetime parameters introduced by the arguments.
2518
- let lifetime_count_before_args = self . lifetimes_to_define . len ( ) ;
2519
2474
let inputs = self . with_anonymous_lifetime_mode ( lt_mode, |this| {
2520
2475
decl. inputs
2521
2476
. iter ( )
@@ -2530,16 +2485,10 @@ impl<'a> LoweringContext<'a> {
2530
2485
} ) ;
2531
2486
2532
2487
let output = if let Some ( ret_id) = make_ret_async {
2533
- // Calculate the `LtReplacement` to use for any return-position elided
2534
- // lifetimes based on the elided lifetime parameters introduced in the args.
2535
- let lt_replacement = get_elided_lt_replacement (
2536
- & self . lifetimes_to_define [ lifetime_count_before_args..]
2537
- ) ;
2538
2488
self . lower_async_fn_ret_ty (
2539
2489
& decl. output ,
2540
2490
in_band_ty_params. expect ( "`make_ret_async` but no `fn_def_id`" ) . 0 ,
2541
2491
ret_id,
2542
- lt_replacement,
2543
2492
)
2544
2493
} else {
2545
2494
match decl. output {
@@ -2604,7 +2553,6 @@ impl<'a> LoweringContext<'a> {
2604
2553
output : & FunctionRetTy ,
2605
2554
fn_def_id : DefId ,
2606
2555
opaque_ty_node_id : NodeId ,
2607
- elided_lt_replacement : LtReplacement ,
2608
2556
) -> hir:: FunctionRetTy {
2609
2557
let span = output. span ( ) ;
2610
2558
@@ -2622,9 +2570,18 @@ impl<'a> LoweringContext<'a> {
2622
2570
2623
2571
self . allocate_hir_id_counter ( opaque_ty_node_id) ;
2624
2572
2573
+ let input_lifetimes_count = self . in_scope_lifetimes . len ( ) + self . lifetimes_to_define . len ( ) ;
2625
2574
let ( opaque_ty_id, lifetime_params) = self . with_hir_id_owner ( opaque_ty_node_id, |this| {
2575
+ // We have to be careful to get elision right here. The
2576
+ // idea is that we create a lifetime parameter for each
2577
+ // lifetime in the return type. So, given a return type
2578
+ // like `async fn foo(..) -> &[&u32]`, we lower to `impl
2579
+ // Future<Output = &'1 [ &'2 u32 ]>`.
2580
+ //
2581
+ // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
2582
+ // hence the elision takes place at the fn site.
2626
2583
let future_bound = this. with_anonymous_lifetime_mode (
2627
- AnonymousLifetimeMode :: Replace ( elided_lt_replacement ) ,
2584
+ AnonymousLifetimeMode :: CreateParameter ,
2628
2585
|this| this. lower_async_fn_output_type_to_future_bound (
2629
2586
output,
2630
2587
fn_def_id,
@@ -2678,19 +2635,53 @@ impl<'a> LoweringContext<'a> {
2678
2635
( opaque_ty_id, lifetime_params)
2679
2636
} ) ;
2680
2637
2681
- let generic_args =
2682
- lifetime_params
2683
- . iter ( ) . cloned ( )
2684
- . map ( |( span, hir_name) | {
2685
- GenericArg :: Lifetime ( hir:: Lifetime {
2686
- hir_id : self . next_id ( ) ,
2687
- span,
2688
- name : hir:: LifetimeName :: Param ( hir_name) ,
2689
- } )
2638
+ // Create the generic lifetime arguments that we will supply
2639
+ // to the opaque return type. Consider:
2640
+ //
2641
+ // ```rust
2642
+ // async fn foo(x: &u32, ) -> &[&u32] { .. }
2643
+ // ```
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, '_, '_>
2650
+ // ```
2651
+ //
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.
2657
+ let mut generic_args: Vec < _ > =
2658
+ lifetime_params[ ..input_lifetimes_count]
2659
+ . iter ( )
2660
+ . map ( |& ( span, hir_name) | {
2661
+ GenericArg :: Lifetime ( hir:: Lifetime {
2662
+ hir_id : self . next_id ( ) ,
2663
+ span,
2664
+ name : hir:: LifetimeName :: Param ( hir_name) ,
2690
2665
} )
2691
- . collect ( ) ;
2666
+ } )
2667
+ . collect ( ) ;
2668
+ generic_args. extend (
2669
+ lifetime_params[ input_lifetimes_count..]
2670
+ . iter ( )
2671
+ . map ( |& ( span, _) | {
2672
+ GenericArg :: Lifetime ( hir:: Lifetime {
2673
+ hir_id : self . next_id ( ) ,
2674
+ span,
2675
+ name : hir:: LifetimeName :: Implicit ,
2676
+ } )
2677
+ } )
2678
+ ) ;
2692
2679
2693
- let opaque_ty_ref = hir:: TyKind :: Def ( hir:: ItemId { id : opaque_ty_id } , generic_args) ;
2680
+ // Create the `Foo<...>` refernece itself. Note that the `type
2681
+ // Foo = impl Trait` is, internally, created as a child of the
2682
+ // async fn, so the *type parameters* are inherited. It's
2683
+ // only the lifetime parameters that we must supply.
2684
+ let opaque_ty_ref = hir:: TyKind :: Def ( hir:: ItemId { id : opaque_ty_id } , generic_args. into ( ) ) ;
2694
2685
2695
2686
hir:: FunctionRetTy :: Return ( P ( hir:: Ty {
2696
2687
node : opaque_ty_ref,
@@ -2786,11 +2777,6 @@ impl<'a> LoweringContext<'a> {
2786
2777
}
2787
2778
2788
2779
AnonymousLifetimeMode :: ReportError => self . new_error_lifetime ( Some ( l. id ) , span) ,
2789
-
2790
- AnonymousLifetimeMode :: Replace ( replacement) => {
2791
- let hir_id = self . lower_node_id ( l. id ) ;
2792
- self . replace_elided_lifetime ( hir_id, span, replacement)
2793
- }
2794
2780
} ,
2795
2781
ident => {
2796
2782
self . maybe_collect_in_band_lifetime ( ident) ;
@@ -2813,39 +2799,6 @@ impl<'a> LoweringContext<'a> {
2813
2799
}
2814
2800
}
2815
2801
2816
- /// Replace a return-position elided lifetime with the elided lifetime
2817
- /// from the arguments.
2818
- fn replace_elided_lifetime (
2819
- & mut self ,
2820
- hir_id : hir:: HirId ,
2821
- span : Span ,
2822
- replacement : LtReplacement ,
2823
- ) -> hir:: Lifetime {
2824
- let multiple_or_none = match replacement {
2825
- LtReplacement :: Some ( name) => {
2826
- return hir:: Lifetime {
2827
- hir_id,
2828
- span,
2829
- name : hir:: LifetimeName :: Param ( name) ,
2830
- } ;
2831
- }
2832
- LtReplacement :: MultipleLifetimes => "multiple" ,
2833
- LtReplacement :: NoLifetimes => "none" ,
2834
- } ;
2835
-
2836
- let mut err = crate :: middle:: resolve_lifetime:: report_missing_lifetime_specifiers (
2837
- self . sess ,
2838
- span,
2839
- 1 ,
2840
- ) ;
2841
- err. note ( & format ! (
2842
- "return-position elided lifetimes require exactly one \
2843
- input-position elided lifetime, found {}.", multiple_or_none) ) ;
2844
- err. emit ( ) ;
2845
-
2846
- hir:: Lifetime { hir_id, span, name : hir:: LifetimeName :: Error }
2847
- }
2848
-
2849
2802
fn lower_generic_params (
2850
2803
& mut self ,
2851
2804
params : & [ GenericParam ] ,
@@ -5791,10 +5744,6 @@ impl<'a> LoweringContext<'a> {
5791
5744
AnonymousLifetimeMode :: ReportError => self . new_error_lifetime ( None , span) ,
5792
5745
5793
5746
AnonymousLifetimeMode :: PassThrough => self . new_implicit_lifetime ( span) ,
5794
-
5795
- AnonymousLifetimeMode :: Replace ( replacement) => {
5796
- self . new_replacement_lifetime ( replacement, span)
5797
- }
5798
5747
}
5799
5748
}
5800
5749
@@ -5848,10 +5797,6 @@ impl<'a> LoweringContext<'a> {
5848
5797
// This is the normal case.
5849
5798
AnonymousLifetimeMode :: PassThrough => self . new_implicit_lifetime ( span) ,
5850
5799
5851
- AnonymousLifetimeMode :: Replace ( replacement) => {
5852
- self . new_replacement_lifetime ( replacement, span)
5853
- }
5854
-
5855
5800
AnonymousLifetimeMode :: ReportError => self . new_error_lifetime ( None , span) ,
5856
5801
}
5857
5802
}
@@ -5883,25 +5828,11 @@ impl<'a> LoweringContext<'a> {
5883
5828
5884
5829
// This is the normal case.
5885
5830
AnonymousLifetimeMode :: PassThrough => { }
5886
-
5887
- // We don't need to do any replacement here as this lifetime
5888
- // doesn't refer to an elided lifetime elsewhere in the function
5889
- // signature.
5890
- AnonymousLifetimeMode :: Replace ( _) => { }
5891
5831
}
5892
5832
5893
5833
self . new_implicit_lifetime ( span)
5894
5834
}
5895
5835
5896
- fn new_replacement_lifetime (
5897
- & mut self ,
5898
- replacement : LtReplacement ,
5899
- span : Span ,
5900
- ) -> hir:: Lifetime {
5901
- let hir_id = self . next_id ( ) ;
5902
- self . replace_elided_lifetime ( hir_id, span, replacement)
5903
- }
5904
-
5905
5836
fn new_implicit_lifetime ( & mut self , span : Span ) -> hir:: Lifetime {
5906
5837
hir:: Lifetime {
5907
5838
hir_id : self . next_id ( ) ,
0 commit comments