Skip to content

Commit 1d6cebf

Browse files
committed
Implement def_id based remapping
1 parent f0db1d6 commit 1d6cebf

File tree

3 files changed

+140
-107
lines changed

3 files changed

+140
-107
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 133 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -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

156158
impl 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
}

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ pub struct ResolverAstLowering {
177177
pub label_res_map: NodeMap<ast::NodeId>,
178178
/// Resolutions for lifetimes.
179179
pub lifetimes_res_map: NodeMap<LifetimeRes>,
180+
/// Mapping from generics def-id to RPIT copied generic def-id
181+
pub generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
180182
/// Lifetime parameters that lowering will have to introduce.
181183
pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, LifetimeRes)>>,
182184

compiler/rustc_resolve/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,8 @@ pub struct Resolver<'a> {
913913
label_res_map: NodeMap<NodeId>,
914914
/// Resolutions for lifetimes.
915915
lifetimes_res_map: NodeMap<LifetimeRes>,
916+
/// Mapping from generics def-id to RPIT copied generic def-id
917+
generics_def_id_map: Vec<FxHashMap<LocalDefId, LocalDefId>>,
916918
/// Lifetime parameters that lowering will have to introduce.
917919
extra_lifetime_params_map: NodeMap<Vec<(Ident, NodeId, LifetimeRes)>>,
918920

@@ -1277,6 +1279,7 @@ impl<'a> Resolver<'a> {
12771279
import_res_map: Default::default(),
12781280
label_res_map: Default::default(),
12791281
lifetimes_res_map: Default::default(),
1282+
generics_def_id_map: Vec::new(),
12801283
extra_lifetime_params_map: Default::default(),
12811284
extern_crate_map: Default::default(),
12821285
reexport_map: FxHashMap::default(),
@@ -1444,6 +1447,7 @@ impl<'a> Resolver<'a> {
14441447
import_res_map: self.import_res_map,
14451448
label_res_map: self.label_res_map,
14461449
lifetimes_res_map: self.lifetimes_res_map,
1450+
generics_def_id_map: self.generics_def_id_map,
14471451
extra_lifetime_params_map: self.extra_lifetime_params_map,
14481452
next_node_id: self.next_node_id,
14491453
node_id_to_def_id: self.node_id_to_def_id,
@@ -1488,6 +1492,7 @@ impl<'a> Resolver<'a> {
14881492
import_res_map: self.import_res_map.clone(),
14891493
label_res_map: self.label_res_map.clone(),
14901494
lifetimes_res_map: self.lifetimes_res_map.clone(),
1495+
generics_def_id_map: self.generics_def_id_map.clone(),
14911496
extra_lifetime_params_map: self.extra_lifetime_params_map.clone(),
14921497
next_node_id: self.next_node_id.clone(),
14931498
node_id_to_def_id: self.node_id_to_def_id.clone(),

0 commit comments

Comments
 (0)