@@ -151,6 +151,8 @@ trait ResolverAstLoweringExt {
151
151
fn get_lifetime_res ( & self , id : NodeId ) -> Option < LifetimeRes > ;
152
152
fn take_extra_lifetime_params ( & mut self , id : NodeId ) -> Vec < ( Ident , NodeId , LifetimeRes ) > ;
153
153
fn decl_macro_kind ( & self , def_id : LocalDefId ) -> MacroKind ;
154
+ fn record_def_id_remap ( & mut self , from : LocalDefId , to : LocalDefId ) ;
155
+ fn get_remapped_def_id ( & self , local_def_id : LocalDefId ) -> LocalDefId ;
154
156
}
155
157
156
158
impl ResolverAstLoweringExt for ResolverAstLowering {
@@ -218,6 +220,25 @@ impl ResolverAstLoweringExt for ResolverAstLowering {
218
220
fn decl_macro_kind ( & self , def_id : LocalDefId ) -> MacroKind {
219
221
self . builtin_macro_kinds . get ( & def_id) . copied ( ) . unwrap_or ( MacroKind :: Bang )
220
222
}
223
+
224
+ /// Push a remapping into the top-most map. Panics if no map has been pushed.
225
+ #[ tracing:: instrument( level = "debug" , skip( self ) ) ]
226
+ fn record_def_id_remap ( & mut self , from : LocalDefId , to : LocalDefId ) {
227
+ self . generics_def_id_map . last_mut ( ) . expect ( "no map pushed" ) . insert ( from, to) ;
228
+ }
229
+
230
+ fn get_remapped_def_id ( & self , mut local_def_id : LocalDefId ) -> LocalDefId {
231
+ for map in & self . generics_def_id_map {
232
+ if let Some ( r) = map. get ( & local_def_id) {
233
+ debug ! ( "def_id_remapper: remapping from `{local_def_id:?}` to `{r:?}`" ) ;
234
+ local_def_id = * r;
235
+ } else {
236
+ debug ! ( "def_id_remapper: no remapping for `{local_def_id:?}` found in map" ) ;
237
+ }
238
+ }
239
+
240
+ local_def_id
241
+ }
221
242
}
222
243
223
244
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
@@ -474,7 +495,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
474
495
}
475
496
476
497
fn opt_local_def_id ( & self , node : NodeId ) -> Option < LocalDefId > {
477
- self . resolver . node_id_to_def_id . get ( & node) . copied ( )
498
+ self . resolver
499
+ . node_id_to_def_id
500
+ . get ( & node)
501
+ . map ( |local_def_id| self . resolver . get_remapped_def_id ( * local_def_id) )
478
502
}
479
503
480
504
fn local_def_id ( & self , node : NodeId ) -> LocalDefId {
@@ -534,6 +558,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
534
558
debug_assert ! ( _old. is_none( ) )
535
559
}
536
560
561
+ fn with_remapping < R > (
562
+ & mut self ,
563
+ remap : FxHashMap < LocalDefId , LocalDefId > ,
564
+ f : impl FnOnce ( & mut Self ) -> R ,
565
+ ) -> R {
566
+ self . resolver . generics_def_id_map . push ( remap) ;
567
+ let res = f ( self ) ;
568
+ self . resolver . generics_def_id_map . pop ( ) ;
569
+ res
570
+ }
571
+
537
572
fn make_owner_info ( & mut self , node : hir:: OwnerNode < ' hir > ) -> & ' hir hir:: OwnerInfo < ' hir > {
538
573
let attrs = std:: mem:: take ( & mut self . attrs ) ;
539
574
let mut bodies = std:: mem:: take ( & mut self . bodies ) ;
@@ -1325,9 +1360,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1325
1360
let mut new_remapping = FxHashMap :: default ( ) ;
1326
1361
1327
1362
self . with_hir_id_owner ( opaque_ty_node_id, |lctx| {
1328
- let hir_bounds = if origin == hir:: OpaqueTyOrigin :: TyAlias {
1329
- lctx. lower_param_bounds ( bounds, itctx)
1330
- } else {
1363
+ if origin != hir:: OpaqueTyOrigin :: TyAlias {
1331
1364
debug ! ( ?lctx. captured_lifetimes) ;
1332
1365
1333
1366
let lifetime_stash = std:: mem:: replace (
@@ -1347,53 +1380,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1347
1380
& mut new_remapping,
1348
1381
) ;
1349
1382
1350
- let ret = lctx. lower_param_bounds ( bounds, itctx) ;
1351
-
1352
1383
let ctxt = std:: mem:: replace ( & mut lctx. captured_lifetimes , lifetime_stash) . unwrap ( ) ;
1353
1384
1354
1385
collected_lifetimes = ctxt. captures ;
1355
-
1356
- ret
1357
1386
} ;
1387
+ debug ! ( ?new_remapping) ;
1358
1388
debug ! ( ?collected_lifetimes) ;
1359
1389
1360
- let lifetime_defs =
1361
- lctx. arena . alloc_from_iter ( collected_lifetimes. iter ( ) . map ( |& ( lifetime, _) | {
1362
- let hir_id = lctx. lower_node_id ( lifetime. id ) ;
1363
- debug_assert_ne ! ( lctx. opt_local_def_id( lifetime. id) , None ) ;
1390
+ lctx. with_remapping ( new_remapping, |lctx| {
1391
+ let hir_bounds = lctx. lower_param_bounds ( bounds, itctx) ;
1392
+
1393
+ let lifetime_defs =
1394
+ lctx. arena . alloc_from_iter ( collected_lifetimes. iter ( ) . map ( |& ( lifetime, _) | {
1395
+ let hir_id = lctx. lower_node_id ( lifetime. id ) ;
1396
+ debug_assert_ne ! ( lctx. opt_local_def_id( lifetime. id) , None ) ;
1397
+
1398
+ let ( name, kind) = if lifetime. ident . name == kw:: UnderscoreLifetime {
1399
+ ( hir:: ParamName :: Fresh , hir:: LifetimeParamKind :: Elided )
1400
+ } else {
1401
+ (
1402
+ hir:: ParamName :: Plain ( lifetime. ident ) ,
1403
+ hir:: LifetimeParamKind :: Explicit ,
1404
+ )
1405
+ } ;
1364
1406
1365
- let ( name, kind) = if lifetime. ident . name == kw:: UnderscoreLifetime {
1366
- ( hir:: ParamName :: Fresh , hir:: LifetimeParamKind :: Elided )
1367
- } else {
1368
- ( hir:: ParamName :: Plain ( lifetime. ident ) , hir:: LifetimeParamKind :: Explicit )
1369
- } ;
1407
+ hir:: GenericParam {
1408
+ hir_id,
1409
+ name,
1410
+ span : lifetime. ident . span ,
1411
+ pure_wrt_drop : false ,
1412
+ kind : hir:: GenericParamKind :: Lifetime { kind } ,
1413
+ colon_span : None ,
1414
+ }
1415
+ } ) ) ;
1370
1416
1371
- hir:: GenericParam {
1372
- hir_id,
1373
- name,
1374
- span : lifetime. ident . span ,
1375
- pure_wrt_drop : false ,
1376
- kind : hir:: GenericParamKind :: Lifetime { kind } ,
1377
- colon_span : None ,
1378
- }
1379
- } ) ) ;
1380
-
1381
- debug ! ( "lower_opaque_impl_trait: lifetime_defs={:#?}" , lifetime_defs) ;
1382
-
1383
- let opaque_ty_item = hir:: OpaqueTy {
1384
- generics : self . arena . alloc ( hir:: Generics {
1385
- params : lifetime_defs,
1386
- predicates : & [ ] ,
1387
- has_where_clause_predicates : false ,
1388
- where_clause_span : lctx. lower_span ( span) ,
1389
- span : lctx. lower_span ( span) ,
1390
- } ) ,
1391
- bounds : hir_bounds,
1392
- origin,
1393
- } ;
1417
+ debug ! ( "lower_opaque_impl_trait: lifetime_defs={:#?}" , lifetime_defs) ;
1418
+
1419
+ let opaque_ty_item = hir:: OpaqueTy {
1420
+ generics : self . arena . alloc ( hir:: Generics {
1421
+ params : lifetime_defs,
1422
+ predicates : & [ ] ,
1423
+ has_where_clause_predicates : false ,
1424
+ where_clause_span : lctx. lower_span ( span) ,
1425
+ span : lctx. lower_span ( span) ,
1426
+ } ) ,
1427
+ bounds : hir_bounds,
1428
+ origin,
1429
+ } ;
1394
1430
1395
- trace ! ( "lower_opaque_impl_trait: {:#?}" , opaque_ty_def_id) ;
1396
- lctx. generate_opaque_type ( opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1431
+ trace ! ( "lower_opaque_impl_trait: {:#?}" , opaque_ty_def_id) ;
1432
+ lctx. generate_opaque_type ( opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1433
+ } )
1397
1434
} ) ;
1398
1435
1399
1436
let lifetimes =
@@ -1746,58 +1783,62 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1746
1783
& mut new_remapping,
1747
1784
) ;
1748
1785
1749
- // We have to be careful to get elision right here. The
1750
- // idea is that we create a lifetime parameter for each
1751
- // lifetime in the return type. So, given a return type
1752
- // like `async fn foo(..) -> &[&u32]`, we lower to `impl
1753
- // Future<Output = &'1 [ &'2 u32 ]>`.
1754
- //
1755
- // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1756
- // hence the elision takes place at the fn site.
1757
- let ret = this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span) ;
1758
-
1759
1786
let ctxt = std:: mem:: replace ( & mut this. captured_lifetimes , lifetime_stash) . unwrap ( ) ;
1760
1787
1761
1788
captures = ctxt. captures ;
1762
1789
1763
- let future_bound = ret;
1764
-
1765
- let generic_params =
1766
- this. arena . alloc_from_iter ( captures. iter ( ) . map ( |& ( lifetime, _) | {
1767
- let hir_id = this. lower_node_id ( lifetime. id ) ;
1768
- debug_assert_ne ! ( this. opt_local_def_id( lifetime. id) , None ) ;
1769
-
1770
- let ( name, kind) = if lifetime. ident . name == kw:: UnderscoreLifetime {
1771
- ( hir:: ParamName :: Fresh , hir:: LifetimeParamKind :: Elided )
1772
- } else {
1773
- ( hir:: ParamName :: Plain ( lifetime. ident ) , hir:: LifetimeParamKind :: Explicit )
1774
- } ;
1790
+ this. with_remapping ( new_remapping, |this| {
1791
+ // We have to be careful to get elision right here. The
1792
+ // idea is that we create a lifetime parameter for each
1793
+ // lifetime in the return type. So, given a return type
1794
+ // like `async fn foo(..) -> &[&u32]`, we lower to `impl
1795
+ // Future<Output = &'1 [ &'2 u32 ]>`.
1796
+ //
1797
+ // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1798
+ // hence the elision takes place at the fn site.
1799
+ let future_bound =
1800
+ this. lower_async_fn_output_type_to_future_bound ( output, fn_def_id, span) ;
1801
+
1802
+ let generic_params =
1803
+ this. arena . alloc_from_iter ( captures. iter ( ) . map ( |& ( lifetime, _) | {
1804
+ let hir_id = this. lower_node_id ( lifetime. id ) ;
1805
+ debug_assert_ne ! ( this. opt_local_def_id( lifetime. id) , None ) ;
1806
+
1807
+ let ( name, kind) = if lifetime. ident . name == kw:: UnderscoreLifetime {
1808
+ ( hir:: ParamName :: Fresh , hir:: LifetimeParamKind :: Elided )
1809
+ } else {
1810
+ (
1811
+ hir:: ParamName :: Plain ( lifetime. ident ) ,
1812
+ hir:: LifetimeParamKind :: Explicit ,
1813
+ )
1814
+ } ;
1775
1815
1776
- hir:: GenericParam {
1777
- hir_id,
1778
- name,
1779
- span : lifetime. ident . span ,
1780
- pure_wrt_drop : false ,
1781
- kind : hir:: GenericParamKind :: Lifetime { kind } ,
1782
- colon_span : None ,
1783
- }
1784
- } ) ) ;
1785
- debug ! ( "lower_async_fn_ret_ty: generic_params={:#?}" , generic_params) ;
1786
-
1787
- let opaque_ty_item = hir:: OpaqueTy {
1788
- generics : this. arena . alloc ( hir:: Generics {
1789
- params : generic_params,
1790
- predicates : & [ ] ,
1791
- has_where_clause_predicates : false ,
1792
- where_clause_span : this. lower_span ( span) ,
1793
- span : this. lower_span ( span) ,
1794
- } ) ,
1795
- bounds : arena_vec ! [ this; future_bound] ,
1796
- origin : hir:: OpaqueTyOrigin :: AsyncFn ( fn_def_id) ,
1797
- } ;
1816
+ hir:: GenericParam {
1817
+ hir_id,
1818
+ name,
1819
+ span : lifetime. ident . span ,
1820
+ pure_wrt_drop : false ,
1821
+ kind : hir:: GenericParamKind :: Lifetime { kind } ,
1822
+ colon_span : None ,
1823
+ }
1824
+ } ) ) ;
1825
+ debug ! ( "lower_async_fn_ret_ty: generic_params={:#?}" , generic_params) ;
1826
+
1827
+ let opaque_ty_item = hir:: OpaqueTy {
1828
+ generics : this. arena . alloc ( hir:: Generics {
1829
+ params : generic_params,
1830
+ predicates : & [ ] ,
1831
+ has_where_clause_predicates : false ,
1832
+ where_clause_span : this. lower_span ( span) ,
1833
+ span : this. lower_span ( span) ,
1834
+ } ) ,
1835
+ bounds : arena_vec ! [ this; future_bound] ,
1836
+ origin : hir:: OpaqueTyOrigin :: AsyncFn ( fn_def_id) ,
1837
+ } ;
1798
1838
1799
- trace ! ( "exist ty from async fn def id: {:#?}" , opaque_ty_def_id) ;
1800
- this. generate_opaque_type ( opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1839
+ trace ! ( "exist ty from async fn def id: {:#?}" , opaque_ty_def_id) ;
1840
+ this. generate_opaque_type ( opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1841
+ } )
1801
1842
} ) ;
1802
1843
1803
1844
// As documented above, we need to create the lifetime
@@ -1910,40 +1951,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1910
1951
ident : Ident ,
1911
1952
res : LifetimeRes ,
1912
1953
) -> hir:: Lifetime {
1913
- debug ! ( ?self . captured_lifetimes) ;
1914
-
1915
1954
let name = match res {
1916
- LifetimeRes :: Param { mut param, .. } => {
1955
+ LifetimeRes :: Param { param, .. } => {
1917
1956
let p_name = ParamName :: Plain ( ident) ;
1918
- if let Some ( mut captured_lifetimes) = self . captured_lifetimes . take ( ) {
1919
- if let Entry :: Occupied ( o) = captured_lifetimes. captures . entry ( param) {
1920
- param = self . local_def_id ( o. get ( ) . 0 . id ) ;
1921
- }
1922
-
1923
- self . captured_lifetimes = Some ( captured_lifetimes) ;
1924
- }
1957
+ let param = self . resolver . get_remapped_def_id ( param) ;
1925
1958
1926
1959
hir:: LifetimeName :: Param ( param, p_name)
1927
1960
}
1928
1961
LifetimeRes :: Fresh { param, .. } => {
1929
1962
debug_assert_eq ! ( ident. name, kw:: UnderscoreLifetime ) ;
1963
+ let param = self . local_def_id ( param) ;
1930
1964
1931
- let mut param = self . local_def_id ( param) ;
1932
- if let Some ( mut captured_lifetimes) = self . captured_lifetimes . take ( ) {
1933
- if let Entry :: Occupied ( o) = captured_lifetimes. captures . entry ( param) {
1934
- param = self . local_def_id ( o. get ( ) . 0 . id ) ;
1935
- }
1936
-
1937
- self . captured_lifetimes = Some ( captured_lifetimes) ;
1938
- }
1939
1965
hir:: LifetimeName :: Param ( param, ParamName :: Fresh )
1940
1966
}
1941
1967
LifetimeRes :: Infer => hir:: LifetimeName :: Infer ,
1942
1968
LifetimeRes :: Static => hir:: LifetimeName :: Static ,
1943
1969
LifetimeRes :: Error => hir:: LifetimeName :: Error ,
1944
1970
res => panic ! ( "Unexpected lifetime resolution {:?} for {:?} at {:?}" , res, ident, span) ,
1945
1971
} ;
1946
- debug ! ( ? self . captured_lifetimes ) ;
1972
+
1947
1973
debug ! ( ?name) ;
1948
1974
hir:: Lifetime { hir_id : self . lower_node_id ( id) , span : self . lower_span ( span) , name }
1949
1975
}
0 commit comments