@@ -341,49 +341,6 @@ enum AnonymousLifetimeMode {
341341
342342 /// Pass responsibility to `resolve_lifetime` code for all cases.
343343 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- }
387344}
388345
389346struct ImplTraitTypeIdVisitor < ' a > { ids : & ' a mut SmallVec < [ NodeId ; 1 ] > }
@@ -2318,8 +2275,7 @@ impl<'a> LoweringContext<'a> {
23182275 err. emit ( ) ;
23192276 }
23202277 AnonymousLifetimeMode :: PassThrough |
2321- AnonymousLifetimeMode :: ReportError |
2322- AnonymousLifetimeMode :: Replace ( _) => {
2278+ AnonymousLifetimeMode :: ReportError => {
23232279 self . sess . buffer_lint_with_diagnostic (
23242280 ELIDED_LIFETIMES_IN_PATHS ,
23252281 CRATE_NODE_ID ,
@@ -2515,7 +2471,6 @@ impl<'a> LoweringContext<'a> {
25152471
25162472 // Remember how many lifetimes were already around so that we can
25172473 // only look at the lifetime parameters introduced by the arguments.
2518- let lifetime_count_before_args = self . lifetimes_to_define . len ( ) ;
25192474 let inputs = self . with_anonymous_lifetime_mode ( lt_mode, |this| {
25202475 decl. inputs
25212476 . iter ( )
@@ -2530,16 +2485,10 @@ impl<'a> LoweringContext<'a> {
25302485 } ) ;
25312486
25322487 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- ) ;
25382488 self . lower_async_fn_ret_ty (
25392489 & decl. output ,
25402490 in_band_ty_params. expect ( "`make_ret_async` but no `fn_def_id`" ) . 0 ,
25412491 ret_id,
2542- lt_replacement,
25432492 )
25442493 } else {
25452494 match decl. output {
@@ -2604,7 +2553,6 @@ impl<'a> LoweringContext<'a> {
26042553 output : & FunctionRetTy ,
26052554 fn_def_id : DefId ,
26062555 opaque_ty_node_id : NodeId ,
2607- elided_lt_replacement : LtReplacement ,
26082556 ) -> hir:: FunctionRetTy {
26092557 let span = output. span ( ) ;
26102558
@@ -2622,9 +2570,18 @@ impl<'a> LoweringContext<'a> {
26222570
26232571 self . allocate_hir_id_counter ( opaque_ty_node_id) ;
26242572
2573+ let input_lifetimes_count = self . in_scope_lifetimes . len ( ) + self . lifetimes_to_define . len ( ) ;
26252574 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.
26262583 let future_bound = this. with_anonymous_lifetime_mode (
2627- AnonymousLifetimeMode :: Replace ( elided_lt_replacement ) ,
2584+ AnonymousLifetimeMode :: CreateParameter ,
26282585 |this| this. lower_async_fn_output_type_to_future_bound (
26292586 output,
26302587 fn_def_id,
@@ -2678,19 +2635,53 @@ impl<'a> LoweringContext<'a> {
26782635 ( opaque_ty_id, lifetime_params)
26792636 } ) ;
26802637
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) ,
26902665 } )
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+ ) ;
26922679
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 ( ) ) ;
26942685
26952686 hir:: FunctionRetTy :: Return ( P ( hir:: Ty {
26962687 node : opaque_ty_ref,
@@ -2786,11 +2777,6 @@ impl<'a> LoweringContext<'a> {
27862777 }
27872778
27882779 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- }
27942780 } ,
27952781 ident => {
27962782 self . maybe_collect_in_band_lifetime ( ident) ;
@@ -2813,39 +2799,6 @@ impl<'a> LoweringContext<'a> {
28132799 }
28142800 }
28152801
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-
28492802 fn lower_generic_params (
28502803 & mut self ,
28512804 params : & [ GenericParam ] ,
@@ -5791,10 +5744,6 @@ impl<'a> LoweringContext<'a> {
57915744 AnonymousLifetimeMode :: ReportError => self . new_error_lifetime ( None , span) ,
57925745
57935746 AnonymousLifetimeMode :: PassThrough => self . new_implicit_lifetime ( span) ,
5794-
5795- AnonymousLifetimeMode :: Replace ( replacement) => {
5796- self . new_replacement_lifetime ( replacement, span)
5797- }
57985747 }
57995748 }
58005749
@@ -5848,10 +5797,6 @@ impl<'a> LoweringContext<'a> {
58485797 // This is the normal case.
58495798 AnonymousLifetimeMode :: PassThrough => self . new_implicit_lifetime ( span) ,
58505799
5851- AnonymousLifetimeMode :: Replace ( replacement) => {
5852- self . new_replacement_lifetime ( replacement, span)
5853- }
5854-
58555800 AnonymousLifetimeMode :: ReportError => self . new_error_lifetime ( None , span) ,
58565801 }
58575802 }
@@ -5883,25 +5828,11 @@ impl<'a> LoweringContext<'a> {
58835828
58845829 // This is the normal case.
58855830 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 ( _) => { }
58915831 }
58925832
58935833 self . new_implicit_lifetime ( span)
58945834 }
58955835
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-
59055836 fn new_implicit_lifetime ( & mut self , span : Span ) -> hir:: Lifetime {
59065837 hir:: Lifetime {
59075838 hir_id : self . next_id ( ) ,
0 commit comments