@@ -129,20 +129,16 @@ struct LoweringContext<'a, 'hir: 'a> {
129129 /// written at all (e.g., `&T` or `std::cell::Ref<T>`).
130130 anonymous_lifetime_mode : AnonymousLifetimeMode ,
131131
132- /// Used to create lifetime definitions from in-band lifetime usages.
133- /// e.g., `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
134- /// When a named lifetime is encountered in a function or impl header and
135- /// has not been defined
136- /// (i.e., it doesn't appear in the in_scope_lifetimes list), it is added
132+ /// Used to create lifetime definitions for anonymous lifetimes.
133+ /// When an anonymous lifetime is encountered in a function or impl header and
134+ /// requires to create a fresh lifetime parameter, it is added
137135 /// to this list. The results of this list are then added to the list of
138136 /// lifetime definitions in the corresponding impl or function generics.
139- lifetimes_to_define : Vec < ( Span , ParamName ) > ,
137+ lifetimes_to_define : Vec < ( Span , NodeId ) > ,
140138
141- /// `true` if in-band lifetimes are being collected. This is used to
142- /// indicate whether or not we're in a place where new lifetimes will result
143- /// in in-band lifetime definitions, such a function or an impl header,
144- /// including implicit lifetimes from `impl_header_lifetime_elision`.
145- is_collecting_anonymous_lifetimes : bool ,
139+ /// If anonymous lifetimes are being collected, this field holds the parent
140+ /// `LocalDefId` to create the fresh lifetime parameters' `LocalDefId`.
141+ is_collecting_anonymous_lifetimes : Option < LocalDefId > ,
146142
147143 /// Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
148144 /// We always store a `normalize_to_macros_2_0()` version of the param-name in this
@@ -375,7 +371,7 @@ pub fn lower_crate<'a, 'hir>(
375371 task_context : None ,
376372 current_item : None ,
377373 lifetimes_to_define : Vec :: new ( ) ,
378- is_collecting_anonymous_lifetimes : false ,
374+ is_collecting_anonymous_lifetimes : None ,
379375 in_scope_lifetimes : Vec :: new ( ) ,
380376 allow_try_trait : Some ( [ sym:: try_trait_v2] [ ..] . into ( ) ) ,
381377 allow_gen_future : Some ( [ sym:: gen_future] [ ..] . into ( ) ) ,
@@ -720,9 +716,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
720716 /// parameter while `f` is running (and restored afterwards).
721717 fn collect_in_band_defs < T > (
722718 & mut self ,
719+ parent_def_id : LocalDefId ,
723720 f : impl FnOnce ( & mut Self ) -> T ,
724- ) -> ( Vec < ( Span , ParamName ) > , T ) {
725- let was_collecting = std:: mem:: replace ( & mut self . is_collecting_anonymous_lifetimes , true ) ;
721+ ) -> ( Vec < ( Span , NodeId ) > , T ) {
722+ let was_collecting =
723+ std:: mem:: replace ( & mut self . is_collecting_anonymous_lifetimes , Some ( parent_def_id) ) ;
726724 let len = self . lifetimes_to_define . len ( ) ;
727725
728726 let res = f ( self ) ;
@@ -733,49 +731,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
733731 }
734732
735733 /// Converts a lifetime into a new generic parameter.
736- fn lifetime_to_generic_param (
734+ fn fresh_lifetime_to_generic_param (
737735 & mut self ,
738736 span : Span ,
739- hir_name : ParamName ,
740- parent_def_id : LocalDefId ,
737+ node_id : NodeId ,
741738 ) -> hir:: GenericParam < ' hir > {
742- let node_id = self . resolver . next_node_id ( ) ;
743-
744- // Get the name we'll use to make the def-path. Note
745- // that collisions are ok here and this shouldn't
746- // really show up for end-user.
747- let ( str_name, kind) = match hir_name {
748- ParamName :: Plain ( ident) => ( ident. name , hir:: LifetimeParamKind :: Explicit ) ,
749- ParamName :: Fresh ( _) => ( kw:: UnderscoreLifetime , hir:: LifetimeParamKind :: Elided ) ,
750- ParamName :: Error => ( kw:: UnderscoreLifetime , hir:: LifetimeParamKind :: Error ) ,
751- } ;
752-
753- // Add a definition for the in-band lifetime def.
754- self . resolver . create_def (
755- parent_def_id,
756- node_id,
757- DefPathData :: LifetimeNs ( str_name) ,
758- ExpnId :: root ( ) ,
759- span. with_parent ( None ) ,
760- ) ;
761-
739+ let hir_id = self . lower_node_id ( node_id) ;
740+ let def_id = self . resolver . local_def_id ( node_id) ;
762741 hir:: GenericParam {
763- hir_id : self . lower_node_id ( node_id ) ,
764- name : hir_name ,
742+ hir_id,
743+ name : hir :: ParamName :: Fresh ( def_id ) ,
765744 bounds : & [ ] ,
766745 span : self . lower_span ( span) ,
767746 pure_wrt_drop : false ,
768- kind : hir:: GenericParamKind :: Lifetime { kind } ,
747+ kind : hir:: GenericParamKind :: Lifetime { kind : hir :: LifetimeParamKind :: Elided } ,
769748 }
770749 }
771750
772751 /// When we have either an elided or `'_` lifetime in an impl
773752 /// header, we convert it to an in-band lifetime.
774753 fn collect_fresh_anonymous_lifetime ( & mut self , span : Span ) -> ParamName {
775- assert ! ( self . is_collecting_anonymous_lifetimes) ;
776- let index = self . lifetimes_to_define . len ( ) + self . in_scope_lifetimes . len ( ) ;
777- let hir_name = ParamName :: Fresh ( index) ;
778- self . lifetimes_to_define . push ( ( span, hir_name) ) ;
754+ let Some ( parent_def_id) = self . is_collecting_anonymous_lifetimes else { panic ! ( ) } ;
755+
756+ let node_id = self . resolver . next_node_id ( ) ;
757+
758+ // Add a definition for the in-band lifetime def.
759+ let param_def_id = self . resolver . create_def (
760+ parent_def_id,
761+ node_id,
762+ DefPathData :: LifetimeNs ( kw:: UnderscoreLifetime ) ,
763+ ExpnId :: root ( ) ,
764+ span. with_parent ( None ) ,
765+ ) ;
766+
767+ let hir_name = ParamName :: Fresh ( param_def_id) ;
768+ self . lifetimes_to_define . push ( ( span, node_id) ) ;
779769 hir_name
780770 }
781771
@@ -817,7 +807,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
817807 f : impl FnOnce ( & mut Self , & mut Vec < hir:: GenericParam < ' hir > > ) -> T ,
818808 ) -> ( hir:: Generics < ' hir > , T ) {
819809 let ( lifetimes_to_define, ( mut lowered_generics, impl_trait_defs, res) ) = self
820- . collect_in_band_defs ( |this| {
810+ . collect_in_band_defs ( parent_def_id , |this| {
821811 this. with_anonymous_lifetime_mode ( anonymous_lifetime_mode, |this| {
822812 this. with_in_scope_lifetime_defs ( & generics. params , |this| {
823813 let mut impl_trait_defs = Vec :: new ( ) ;
@@ -844,9 +834,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
844834 lowered_generics. params . extend (
845835 lifetimes_to_define
846836 . into_iter ( )
847- . map ( |( span, hir_name) | {
848- self . lifetime_to_generic_param ( span, hir_name, parent_def_id)
849- } )
837+ . map ( |( span, node_id) | self . fresh_lifetime_to_generic_param ( span, node_id) )
850838 . chain ( impl_trait_defs) ,
851839 ) ;
852840
@@ -1763,15 +1751,53 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17631751 . in_scope_lifetimes
17641752 . iter ( )
17651753 . cloned ( )
1766- . map ( |name| ( name. ident ( ) . span , name , hir:: LifetimeName :: Param ( name) ) )
1767- . chain (
1768- self . lifetimes_to_define
1769- . iter ( )
1770- . map ( | & ( span, name ) | ( span , name , hir:: LifetimeName :: Param ( name) ) ) ,
1771- )
1754+ . map ( |name| ( name. ident ( ) . span , hir:: LifetimeName :: Param ( name) ) )
1755+ . chain ( self . lifetimes_to_define . iter ( ) . map ( | & ( span , node_id ) | {
1756+ let def_id = self . resolver . local_def_id ( node_id ) ;
1757+ let name = hir :: ParamName :: Fresh ( def_id ) ;
1758+ ( span, hir:: LifetimeName :: Param ( name) )
1759+ } ) )
17721760 . collect ( ) ;
17731761
17741762 self . with_hir_id_owner ( opaque_ty_node_id, |this| {
1763+ let mut generic_params: Vec < _ > = lifetime_params
1764+ . iter ( )
1765+ . map ( |& ( span, name) | {
1766+ // We can only get lifetime names from the outside.
1767+ let hir:: LifetimeName :: Param ( hir_name) = name else { panic ! ( ) } ;
1768+
1769+ let node_id = this. resolver . next_node_id ( ) ;
1770+
1771+ // Add a definition for the in-band lifetime def.
1772+ let def_id = this. resolver . create_def (
1773+ opaque_ty_def_id,
1774+ node_id,
1775+ DefPathData :: LifetimeNs ( hir_name. ident ( ) . name ) ,
1776+ ExpnId :: root ( ) ,
1777+ span. with_parent ( None ) ,
1778+ ) ;
1779+
1780+ let ( kind, name) = match hir_name {
1781+ ParamName :: Plain ( ident) => {
1782+ ( hir:: LifetimeParamKind :: Explicit , hir:: ParamName :: Plain ( ident) )
1783+ }
1784+ ParamName :: Fresh ( _) => {
1785+ ( hir:: LifetimeParamKind :: Elided , hir:: ParamName :: Fresh ( def_id) )
1786+ }
1787+ ParamName :: Error => ( hir:: LifetimeParamKind :: Error , hir:: ParamName :: Error ) ,
1788+ } ;
1789+
1790+ hir:: GenericParam {
1791+ hir_id : this. lower_node_id ( node_id) ,
1792+ name,
1793+ bounds : & [ ] ,
1794+ span : this. lower_span ( span) ,
1795+ pure_wrt_drop : false ,
1796+ kind : hir:: GenericParamKind :: Lifetime { kind } ,
1797+ }
1798+ } )
1799+ . collect ( ) ;
1800+
17751801 // We have to be careful to get elision right here. The
17761802 // idea is that we create a lifetime parameter for each
17771803 // lifetime in the return type. So, given a return type
@@ -1782,25 +1808,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17821808 // hence the elision takes place at the fn site.
17831809 let ( lifetimes_to_define, future_bound) =
17841810 this. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: CreateParameter , |this| {
1785- this. collect_in_band_defs ( |this| {
1811+ this. collect_in_band_defs ( opaque_ty_def_id , |this| {
17861812 this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
17871813 } )
17881814 } ) ;
17891815 debug ! ( "lower_async_fn_ret_ty: future_bound={:#?}" , future_bound) ;
17901816 debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , lifetimes_to_define) ;
17911817
1792- lifetime_params. extend (
1793- // Output lifetime like `'_`:
1794- lifetimes_to_define
1795- . into_iter ( )
1796- . map ( |( span, name) | ( span, name, hir:: LifetimeName :: Implicit ( false ) ) ) ,
1797- ) ;
1818+ // Output lifetime like `'_`:
1819+ for ( span, node_id) in lifetimes_to_define {
1820+ let param = this. fresh_lifetime_to_generic_param ( span, node_id) ;
1821+ lifetime_params. push ( ( span, hir:: LifetimeName :: Implicit ( false ) ) ) ;
1822+ generic_params. push ( param) ;
1823+ }
1824+ let generic_params = this. arena . alloc_from_iter ( generic_params) ;
17981825 debug ! ( "lower_async_fn_ret_ty: lifetime_params={:#?}" , lifetime_params) ;
1799-
1800- let generic_params =
1801- this. arena . alloc_from_iter ( lifetime_params. iter ( ) . map ( |& ( span, hir_name, _) | {
1802- this. lifetime_to_generic_param ( span, hir_name, opaque_ty_def_id)
1803- } ) ) ;
1826+ debug ! ( "lower_async_fn_ret_ty: generic_params={:#?}" , generic_params) ;
18041827
18051828 let opaque_ty_item = hir:: OpaqueTy {
18061829 generics : hir:: Generics {
@@ -1833,7 +1856,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18331856 // For the "output" lifetime parameters, we just want to
18341857 // generate `'_`.
18351858 let generic_args =
1836- self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, _ , name) | {
1859+ self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, name) | {
18371860 GenericArg :: Lifetime ( hir:: Lifetime {
18381861 hir_id : self . next_id ( ) ,
18391862 span : self . lower_span ( span) ,
@@ -1969,7 +1992,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19691992 let ( name, kind) = match param. kind {
19701993 GenericParamKind :: Lifetime => {
19711994 let was_collecting_in_band = self . is_collecting_anonymous_lifetimes ;
1972- self . is_collecting_anonymous_lifetimes = false ;
1995+ self . is_collecting_anonymous_lifetimes = None ;
19731996
19741997 let lt = self
19751998 . with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: ReportError , |this| {
0 commit comments