@@ -136,13 +136,13 @@ struct LoweringContext<'a, 'hir: 'a> {
136
136
/// (i.e., it doesn't appear in the in_scope_lifetimes list), it is added
137
137
/// to this list. The results of this list are then added to the list of
138
138
/// lifetime definitions in the corresponding impl or function generics.
139
- lifetimes_to_define : Vec < ( Span , ParamName ) > ,
139
+ lifetimes_to_define : Vec < ( Span , NodeId ) > ,
140
140
141
141
/// `true` if in-band lifetimes are being collected. This is used to
142
142
/// indicate whether or not we're in a place where new lifetimes will result
143
143
/// in in-band lifetime definitions, such a function or an impl header,
144
144
/// including implicit lifetimes from `impl_header_lifetime_elision`.
145
- is_collecting_anonymous_lifetimes : bool ,
145
+ is_collecting_anonymous_lifetimes : Option < LocalDefId > ,
146
146
147
147
/// Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
148
148
/// We always store a `normalize_to_macros_2_0()` version of the param-name in this
@@ -375,7 +375,7 @@ pub fn lower_crate<'a, 'hir>(
375
375
task_context : None ,
376
376
current_item : None ,
377
377
lifetimes_to_define : Vec :: new ( ) ,
378
- is_collecting_anonymous_lifetimes : false ,
378
+ is_collecting_anonymous_lifetimes : None ,
379
379
in_scope_lifetimes : Vec :: new ( ) ,
380
380
allow_try_trait : Some ( [ sym:: try_trait_v2] [ ..] . into ( ) ) ,
381
381
allow_gen_future : Some ( [ sym:: gen_future] [ ..] . into ( ) ) ,
@@ -720,9 +720,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
720
720
/// parameter while `f` is running (and restored afterwards).
721
721
fn collect_in_band_defs < T > (
722
722
& mut self ,
723
+ parent_def_id : LocalDefId ,
723
724
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 ) ;
725
+ ) -> ( Vec < ( Span , NodeId ) > , T ) {
726
+ let was_collecting =
727
+ std:: mem:: replace ( & mut self . is_collecting_anonymous_lifetimes , Some ( parent_def_id) ) ;
726
728
let len = self . lifetimes_to_define . len ( ) ;
727
729
728
730
let res = f ( self ) ;
@@ -733,49 +735,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
733
735
}
734
736
735
737
/// Converts a lifetime into a new generic parameter.
736
- fn lifetime_to_generic_param (
738
+ fn fresh_lifetime_to_generic_param (
737
739
& mut self ,
738
740
span : Span ,
739
- hir_name : ParamName ,
740
- parent_def_id : LocalDefId ,
741
+ node_id : NodeId ,
741
742
) -> 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
-
743
+ let hir_id = self . lower_node_id ( node_id) ;
744
+ let def_id = self . resolver . local_def_id ( node_id) ;
762
745
hir:: GenericParam {
763
- hir_id : self . lower_node_id ( node_id ) ,
764
- name : hir_name ,
746
+ hir_id,
747
+ name : hir :: ParamName :: Fresh ( def_id ) ,
765
748
bounds : & [ ] ,
766
749
span : self . lower_span ( span) ,
767
750
pure_wrt_drop : false ,
768
- kind : hir:: GenericParamKind :: Lifetime { kind } ,
751
+ kind : hir:: GenericParamKind :: Lifetime { kind : hir :: LifetimeParamKind :: Elided } ,
769
752
}
770
753
}
771
754
772
755
/// When we have either an elided or `'_` lifetime in an impl
773
756
/// header, we convert it to an in-band lifetime.
774
757
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) ) ;
758
+ let Some ( parent_def_id) = self . is_collecting_anonymous_lifetimes else { panic ! ( ) } ;
759
+
760
+ let node_id = self . resolver . next_node_id ( ) ;
761
+
762
+ // Add a definition for the in-band lifetime def.
763
+ let param_def_id = self . resolver . create_def (
764
+ parent_def_id,
765
+ node_id,
766
+ DefPathData :: LifetimeNs ( kw:: UnderscoreLifetime ) ,
767
+ ExpnId :: root ( ) ,
768
+ span. with_parent ( None ) ,
769
+ ) ;
770
+
771
+ let hir_name = ParamName :: Fresh ( param_def_id) ;
772
+ self . lifetimes_to_define . push ( ( span, node_id) ) ;
779
773
hir_name
780
774
}
781
775
@@ -817,7 +811,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
817
811
f : impl FnOnce ( & mut Self , & mut Vec < hir:: GenericParam < ' hir > > ) -> T ,
818
812
) -> ( hir:: Generics < ' hir > , T ) {
819
813
let ( lifetimes_to_define, ( mut lowered_generics, impl_trait_defs, res) ) = self
820
- . collect_in_band_defs ( |this| {
814
+ . collect_in_band_defs ( parent_def_id , |this| {
821
815
this. with_anonymous_lifetime_mode ( anonymous_lifetime_mode, |this| {
822
816
this. with_in_scope_lifetime_defs ( & generics. params , |this| {
823
817
let mut impl_trait_defs = Vec :: new ( ) ;
@@ -844,9 +838,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
844
838
lowered_generics. params . extend (
845
839
lifetimes_to_define
846
840
. into_iter ( )
847
- . map ( |( span, hir_name) | {
848
- self . lifetime_to_generic_param ( span, hir_name, parent_def_id)
849
- } )
841
+ . map ( |( span, node_id) | self . fresh_lifetime_to_generic_param ( span, node_id) )
850
842
. chain ( impl_trait_defs) ,
851
843
) ;
852
844
@@ -1763,15 +1755,53 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1763
1755
. in_scope_lifetimes
1764
1756
. iter ( )
1765
1757
. 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
- )
1758
+ . map ( |name| ( name. ident ( ) . span , hir:: LifetimeName :: Param ( name) ) )
1759
+ . chain ( self . lifetimes_to_define . iter ( ) . map ( | & ( span , node_id ) | {
1760
+ let def_id = self . resolver . local_def_id ( node_id ) ;
1761
+ let name = hir :: ParamName :: Fresh ( def_id ) ;
1762
+ ( span, hir:: LifetimeName :: Param ( name) )
1763
+ } ) )
1772
1764
. collect ( ) ;
1773
1765
1774
1766
self . with_hir_id_owner ( opaque_ty_node_id, |this| {
1767
+ let mut generic_params: Vec < _ > = lifetime_params
1768
+ . iter ( )
1769
+ . map ( |& ( span, name) | {
1770
+ // We can only get lifetime names from the outside.
1771
+ let hir:: LifetimeName :: Param ( hir_name) = name else { panic ! ( ) } ;
1772
+
1773
+ let node_id = this. resolver . next_node_id ( ) ;
1774
+
1775
+ // Add a definition for the in-band lifetime def.
1776
+ let def_id = this. resolver . create_def (
1777
+ opaque_ty_def_id,
1778
+ node_id,
1779
+ DefPathData :: LifetimeNs ( hir_name. ident ( ) . name ) ,
1780
+ ExpnId :: root ( ) ,
1781
+ span. with_parent ( None ) ,
1782
+ ) ;
1783
+
1784
+ let ( kind, name) = match hir_name {
1785
+ ParamName :: Plain ( ident) => {
1786
+ ( hir:: LifetimeParamKind :: Explicit , hir:: ParamName :: Plain ( ident) )
1787
+ }
1788
+ ParamName :: Fresh ( _) => {
1789
+ ( hir:: LifetimeParamKind :: Elided , hir:: ParamName :: Fresh ( def_id) )
1790
+ }
1791
+ ParamName :: Error => ( hir:: LifetimeParamKind :: Error , hir:: ParamName :: Error ) ,
1792
+ } ;
1793
+
1794
+ hir:: GenericParam {
1795
+ hir_id : this. lower_node_id ( node_id) ,
1796
+ name,
1797
+ bounds : & [ ] ,
1798
+ span : this. lower_span ( span) ,
1799
+ pure_wrt_drop : false ,
1800
+ kind : hir:: GenericParamKind :: Lifetime { kind } ,
1801
+ }
1802
+ } )
1803
+ . collect ( ) ;
1804
+
1775
1805
// We have to be careful to get elision right here. The
1776
1806
// idea is that we create a lifetime parameter for each
1777
1807
// lifetime in the return type. So, given a return type
@@ -1782,25 +1812,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1782
1812
// hence the elision takes place at the fn site.
1783
1813
let ( lifetimes_to_define, future_bound) =
1784
1814
this. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: CreateParameter , |this| {
1785
- this. collect_in_band_defs ( |this| {
1815
+ this. collect_in_band_defs ( opaque_ty_def_id , |this| {
1786
1816
this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span)
1787
1817
} )
1788
1818
} ) ;
1789
1819
debug ! ( "lower_async_fn_ret_ty: future_bound={:#?}" , future_bound) ;
1790
1820
debug ! ( "lower_async_fn_ret_ty: lifetimes_to_define={:#?}" , lifetimes_to_define) ;
1791
1821
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
- ) ;
1822
+ // Output lifetime like `'_`:
1823
+ for ( span, node_id) in lifetimes_to_define {
1824
+ let param = this. fresh_lifetime_to_generic_param ( span, node_id) ;
1825
+ lifetime_params. push ( ( span, hir:: LifetimeName :: Implicit ( false ) ) ) ;
1826
+ generic_params. push ( param) ;
1827
+ }
1828
+ let generic_params = this. arena . alloc_from_iter ( generic_params) ;
1798
1829
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
- } ) ) ;
1830
+ debug ! ( "lower_async_fn_ret_ty: generic_params={:#?}" , generic_params) ;
1804
1831
1805
1832
let opaque_ty_item = hir:: OpaqueTy {
1806
1833
generics : hir:: Generics {
@@ -1833,7 +1860,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1833
1860
// For the "output" lifetime parameters, we just want to
1834
1861
// generate `'_`.
1835
1862
let generic_args =
1836
- self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, _ , name) | {
1863
+ self . arena . alloc_from_iter ( lifetime_params. into_iter ( ) . map ( |( span, name) | {
1837
1864
GenericArg :: Lifetime ( hir:: Lifetime {
1838
1865
hir_id : self . next_id ( ) ,
1839
1866
span : self . lower_span ( span) ,
@@ -1969,7 +1996,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1969
1996
let ( name, kind) = match param. kind {
1970
1997
GenericParamKind :: Lifetime => {
1971
1998
let was_collecting_in_band = self . is_collecting_anonymous_lifetimes ;
1972
- self . is_collecting_anonymous_lifetimes = false ;
1999
+ self . is_collecting_anonymous_lifetimes = None ;
1973
2000
1974
2001
let lt = self
1975
2002
. with_anonymous_lifetime_mode ( AnonymousLifetimeMode :: ReportError , |this| {
0 commit comments