@@ -129,20 +129,16 @@ struct LoweringContext<'a, 'hir: 'a> {
129
129
/// written at all (e.g., `&T` or `std::cell::Ref<T>`).
130
130
anonymous_lifetime_mode : AnonymousLifetimeMode ,
131
131
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
137
135
/// to this list. The results of this list are then added to the list of
138
136
/// lifetime definitions in the corresponding impl or function generics.
139
- lifetimes_to_define : Vec < ( Span , ParamName ) > ,
137
+ lifetimes_to_define : Vec < ( Span , NodeId ) > ,
140
138
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 > ,
146
142
147
143
/// Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
148
144
/// 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>(
375
371
task_context : None ,
376
372
current_item : None ,
377
373
lifetimes_to_define : Vec :: new ( ) ,
378
- is_collecting_anonymous_lifetimes : false ,
374
+ is_collecting_anonymous_lifetimes : None ,
379
375
in_scope_lifetimes : Vec :: new ( ) ,
380
376
allow_try_trait : Some ( [ sym:: try_trait_v2] [ ..] . into ( ) ) ,
381
377
allow_gen_future : Some ( [ sym:: gen_future] [ ..] . into ( ) ) ,
@@ -720,9 +716,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
720
716
/// parameter while `f` is running (and restored afterwards).
721
717
fn collect_in_band_defs < T > (
722
718
& mut self ,
719
+ parent_def_id : LocalDefId ,
723
720
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) ) ;
726
724
let len = self . lifetimes_to_define . len ( ) ;
727
725
728
726
let res = f ( self ) ;
@@ -733,49 +731,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
733
731
}
734
732
735
733
/// Converts a lifetime into a new generic parameter.
736
- fn lifetime_to_generic_param (
734
+ fn fresh_lifetime_to_generic_param (
737
735
& mut self ,
738
736
span : Span ,
739
- hir_name : ParamName ,
740
- parent_def_id : LocalDefId ,
737
+ node_id : NodeId ,
741
738
) -> 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) ;
762
741
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 ) ,
765
744
bounds : & [ ] ,
766
745
span : self . lower_span ( span) ,
767
746
pure_wrt_drop : false ,
768
- kind : hir:: GenericParamKind :: Lifetime { kind } ,
747
+ kind : hir:: GenericParamKind :: Lifetime { kind : hir :: LifetimeParamKind :: Elided } ,
769
748
}
770
749
}
771
750
772
751
/// When we have either an elided or `'_` lifetime in an impl
773
752
/// header, we convert it to an in-band lifetime.
774
753
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) ) ;
779
769
hir_name
780
770
}
781
771
@@ -817,7 +807,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
817
807
f : impl FnOnce ( & mut Self , & mut Vec < hir:: GenericParam < ' hir > > ) -> T ,
818
808
) -> ( hir:: Generics < ' hir > , T ) {
819
809
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| {
821
811
this. with_anonymous_lifetime_mode ( anonymous_lifetime_mode, |this| {
822
812
this. with_in_scope_lifetime_defs ( & generics. params , |this| {
823
813
let mut impl_trait_defs = Vec :: new ( ) ;
@@ -844,9 +834,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
844
834
lowered_generics. params . extend (
845
835
lifetimes_to_define
846
836
. 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) )
850
838
. chain ( impl_trait_defs) ,
851
839
) ;
852
840
@@ -1763,15 +1751,53 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1763
1751
. in_scope_lifetimes
1764
1752
. iter ( )
1765
1753
. 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
+ } ) )
1772
1760
. collect ( ) ;
1773
1761
1774
1762
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
+
1775
1801
// We have to be careful to get elision right here. The
1776
1802
// idea is that we create a lifetime parameter for each
1777
1803
// lifetime in the return type. So, given a return type
@@ -1782,25 +1808,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1782
1808
// hence the elision takes place at the fn site.
1783
1809
let ( lifetimes_to_define, future_bound) =
1784
1810
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| {
1786
1812
this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
1787
1813
} )
1788
1814
} ) ;
1789
1815
debug ! ( "lower_async_fn_ret_ty: future_bound={:#?}" , future_bound) ;
1790
1816
debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , lifetimes_to_define) ;
1791
1817
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) ;
1798
1825
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) ;
1804
1827
1805
1828
let opaque_ty_item = hir:: OpaqueTy {
1806
1829
generics : hir:: Generics {
@@ -1833,7 +1856,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1833
1856
// For the "output" lifetime parameters, we just want to
1834
1857
// generate `'_`.
1835
1858
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) | {
1837
1860
GenericArg :: Lifetime ( hir:: Lifetime {
1838
1861
hir_id : self . next_id ( ) ,
1839
1862
span : self . lower_span ( span) ,
@@ -1969,7 +1992,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1969
1992
let ( name, kind) = match param. kind {
1970
1993
GenericParamKind :: Lifetime => {
1971
1994
let was_collecting_in_band = self . is_collecting_anonymous_lifetimes ;
1972
- self . is_collecting_anonymous_lifetimes = false ;
1995
+ self . is_collecting_anonymous_lifetimes = None ;
1973
1996
1974
1997
let lt = self
1975
1998
. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: ReportError , |this| {
0 commit comments