@@ -151,6 +151,8 @@ trait ResolverAstLoweringExt {
151151 fn get_lifetime_res ( & self , id : NodeId ) -> Option < LifetimeRes > ;
152152 fn take_extra_lifetime_params ( & mut self , id : NodeId ) -> Vec < ( Ident , NodeId , LifetimeRes ) > ;
153153 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 ;
154156}
155157
156158impl ResolverAstLoweringExt for ResolverAstLowering {
@@ -218,6 +220,25 @@ impl ResolverAstLoweringExt for ResolverAstLowering {
218220 fn decl_macro_kind ( & self , def_id : LocalDefId ) -> MacroKind {
219221 self . builtin_macro_kinds . get ( & def_id) . copied ( ) . unwrap_or ( MacroKind :: Bang )
220222 }
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+ }
221242}
222243
223244/// 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> {
474495 }
475496
476497 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) )
478502 }
479503
480504 fn local_def_id ( & self , node : NodeId ) -> LocalDefId {
@@ -534,6 +558,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
534558 debug_assert ! ( _old. is_none( ) )
535559 }
536560
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+
537572 fn make_owner_info ( & mut self , node : hir:: OwnerNode < ' hir > ) -> & ' hir hir:: OwnerInfo < ' hir > {
538573 let attrs = std:: mem:: take ( & mut self . attrs ) ;
539574 let mut bodies = std:: mem:: take ( & mut self . bodies ) ;
@@ -1325,9 +1360,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13251360 let mut new_remapping = FxHashMap :: default ( ) ;
13261361
13271362 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 {
13311364 debug ! ( ?lctx. captured_lifetimes) ;
13321365
13331366 let lifetime_stash = std:: mem:: replace (
@@ -1347,53 +1380,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13471380 & mut new_remapping,
13481381 ) ;
13491382
1350- let ret = lctx. lower_param_bounds ( bounds, itctx) ;
1351-
13521383 let ctxt = std:: mem:: replace ( & mut lctx. captured_lifetimes , lifetime_stash) . unwrap ( ) ;
13531384
13541385 collected_lifetimes = ctxt. captures ;
1355-
1356- ret
13571386 } ;
1387+ debug ! ( ?new_remapping) ;
13581388 debug ! ( ?collected_lifetimes) ;
13591389
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+ } ;
13641406
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+ } ) ) ;
13701416
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+ } ;
13941430
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+ } )
13971434 } ) ;
13981435
13991436 let lifetimes =
@@ -1746,58 +1783,62 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17461783 & mut new_remapping,
17471784 ) ;
17481785
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-
17591786 let ctxt = std:: mem:: replace ( & mut this. captured_lifetimes , lifetime_stash) . unwrap ( ) ;
17601787
17611788 captures = ctxt. captures ;
17621789
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+ } ;
17751815
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+ } ;
17981838
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+ } )
18011842 } ) ;
18021843
18031844 // As documented above, we need to create the lifetime
@@ -1910,40 +1951,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
19101951 ident : Ident ,
19111952 res : LifetimeRes ,
19121953 ) -> hir:: Lifetime {
1913- debug ! ( ?self . captured_lifetimes) ;
1914-
19151954 let name = match res {
1916- LifetimeRes :: Param { mut param, .. } => {
1955+ LifetimeRes :: Param { param, .. } => {
19171956 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) ;
19251958
19261959 hir:: LifetimeName :: Param ( param, p_name)
19271960 }
19281961 LifetimeRes :: Fresh { param, .. } => {
19291962 debug_assert_eq ! ( ident. name, kw:: UnderscoreLifetime ) ;
1963+ let param = self . local_def_id ( param) ;
19301964
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- }
19391965 hir:: LifetimeName :: Param ( param, ParamName :: Fresh )
19401966 }
19411967 LifetimeRes :: Infer => hir:: LifetimeName :: Infer ,
19421968 LifetimeRes :: Static => hir:: LifetimeName :: Static ,
19431969 LifetimeRes :: Error => hir:: LifetimeName :: Error ,
19441970 res => panic ! ( "Unexpected lifetime resolution {:?} for {:?} at {:?}" , res, ident, span) ,
19451971 } ;
1946- debug ! ( ? self . captured_lifetimes ) ;
1972+
19471973 debug ! ( ?name) ;
19481974 hir:: Lifetime { hir_id : self . lower_node_id ( id) , span : self . lower_span ( span) , name }
19491975 }
0 commit comments