Skip to content

Commit 6431504

Browse files
Eagerly collect mono items for non-generic closures
1 parent 8247594 commit 6431504

File tree

5 files changed

+60
-3
lines changed

5 files changed

+60
-3
lines changed

compiler/rustc_middle/src/hir/map/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
12461246
foreign_items,
12471247
body_owners,
12481248
opaques,
1249+
nested_bodies,
12491250
..
12501251
} = collector;
12511252
ModuleItems {
@@ -1256,6 +1257,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
12561257
foreign_items: foreign_items.into_boxed_slice(),
12571258
body_owners: body_owners.into_boxed_slice(),
12581259
opaques: opaques.into_boxed_slice(),
1260+
nested_bodies: nested_bodies.into_boxed_slice(),
12591261
}
12601262
}
12611263

@@ -1276,6 +1278,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
12761278
foreign_items,
12771279
body_owners,
12781280
opaques,
1281+
nested_bodies,
12791282
..
12801283
} = collector;
12811284

@@ -1287,6 +1290,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
12871290
foreign_items: foreign_items.into_boxed_slice(),
12881291
body_owners: body_owners.into_boxed_slice(),
12891292
opaques: opaques.into_boxed_slice(),
1293+
nested_bodies: nested_bodies.into_boxed_slice(),
12901294
}
12911295
}
12921296

@@ -1302,6 +1306,7 @@ struct ItemCollector<'tcx> {
13021306
foreign_items: Vec<ForeignItemId>,
13031307
body_owners: Vec<LocalDefId>,
13041308
opaques: Vec<LocalDefId>,
1309+
nested_bodies: Vec<LocalDefId>,
13051310
}
13061311

13071312
impl<'tcx> ItemCollector<'tcx> {
@@ -1316,6 +1321,7 @@ impl<'tcx> ItemCollector<'tcx> {
13161321
foreign_items: Vec::default(),
13171322
body_owners: Vec::default(),
13181323
opaques: Vec::default(),
1324+
nested_bodies: Vec::default(),
13191325
}
13201326
}
13211327
}
@@ -1358,6 +1364,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
13581364

13591365
fn visit_inline_const(&mut self, c: &'hir ConstBlock) {
13601366
self.body_owners.push(c.def_id);
1367+
self.nested_bodies.push(c.def_id);
13611368
intravisit::walk_inline_const(self, c)
13621369
}
13631370

@@ -1369,6 +1376,7 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
13691376
fn visit_expr(&mut self, ex: &'hir Expr<'hir>) {
13701377
if let ExprKind::Closure(closure) = ex.kind {
13711378
self.body_owners.push(closure.def_id);
1379+
self.nested_bodies.push(closure.def_id);
13721380
}
13731381
intravisit::walk_expr(self, ex)
13741382
}

compiler/rustc_middle/src/hir/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub struct ModuleItems {
3030
foreign_items: Box<[ForeignItemId]>,
3131
opaques: Box<[LocalDefId]>,
3232
body_owners: Box<[LocalDefId]>,
33+
nested_bodies: Box<[LocalDefId]>,
3334
}
3435

3536
impl ModuleItems {
@@ -70,6 +71,10 @@ impl ModuleItems {
7071
self.opaques.iter().copied()
7172
}
7273

74+
pub fn nested_bodies(&self) -> impl Iterator<Item = LocalDefId> + '_ {
75+
self.nested_bodies.iter().copied()
76+
}
77+
7378
pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> + '_ {
7479
self.owners().map(|id| id.def_id)
7580
}

compiler/rustc_monomorphize/src/collector.rs

+31
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,10 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionStrategy) -> Vec<MonoI
13681368
collector.process_impl_item(id);
13691369
}
13701370

1371+
for id in crate_items.nested_bodies() {
1372+
collector.process_nested_body(id);
1373+
}
1374+
13711375
collector.push_extra_entry_roots();
13721376
}
13731377

@@ -1450,6 +1454,33 @@ impl<'v> RootCollector<'_, 'v> {
14501454
}
14511455
}
14521456

1457+
fn process_nested_body(&mut self, def_id: LocalDefId) {
1458+
match self.tcx.def_kind(def_id) {
1459+
DefKind::Closure => {
1460+
if self.strategy == MonoItemCollectionStrategy::Eager
1461+
&& !self
1462+
.tcx
1463+
.generics_of(self.tcx.typeck_root_def_id(def_id.to_def_id()))
1464+
.requires_monomorphization(self.tcx)
1465+
{
1466+
let instance = match *self.tcx.type_of(def_id).instantiate_identity().kind() {
1467+
ty::Closure(def_id, args)
1468+
| ty::Coroutine(def_id, args)
1469+
| ty::CoroutineClosure(def_id, args) => {
1470+
Instance::new(def_id, self.tcx.erase_regions(args))
1471+
}
1472+
_ => unreachable!(),
1473+
};
1474+
let mono_item = create_fn_mono_item(self.tcx, instance, DUMMY_SP);
1475+
if mono_item.node.is_instantiable(self.tcx) {
1476+
self.output.push(mono_item);
1477+
}
1478+
}
1479+
}
1480+
_ => {}
1481+
}
1482+
}
1483+
14531484
fn is_root(&self, def_id: LocalDefId) -> bool {
14541485
!self.tcx.generics_of(def_id).requires_monomorphization(self.tcx)
14551486
&& match self.strategy {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ edition: 2021
2+
//@ compile-flags: -Zprint-mono-items=eager --crate-type=lib
3+
4+
//~ MONO_ITEM fn async_fn @@
5+
//~ MONO_ITEM fn async_fn::{closure#0} @@
6+
pub async fn async_fn() {}
7+
8+
//~ MONO_ITEM fn closure @@
9+
//~ MONO_ITEM fn closure::{closure#0} @@
10+
pub fn closure() {
11+
let _ = || {};
12+
}

tests/codegen-units/item-collection/non-generic-closures.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ fn temporary() {
1313

1414
//~ MONO_ITEM fn assigned_to_variable_but_not_executed @@ non_generic_closures-cgu.0[Internal]
1515
fn assigned_to_variable_but_not_executed() {
16+
//~ MONO_ITEM fn assigned_to_variable_but_not_executed::{closure#0}
1617
let _x = |a: i16| {
1718
let _ = a + 1;
1819
};
@@ -21,9 +22,9 @@ fn assigned_to_variable_but_not_executed() {
2122
//~ MONO_ITEM fn assigned_to_variable_executed_indirectly @@ non_generic_closures-cgu.0[Internal]
2223
fn assigned_to_variable_executed_indirectly() {
2324
//~ MONO_ITEM fn assigned_to_variable_executed_indirectly::{closure#0} @@ non_generic_closures-cgu.0[Internal]
24-
//~ MONO_ITEM fn <{closure@TEST_PATH:27:13: 27:21} as std::ops::FnOnce<(i32,)>>::call_once - shim @@ non_generic_closures-cgu.0[Internal]
25-
//~ MONO_ITEM fn <{closure@TEST_PATH:27:13: 27:21} as std::ops::FnOnce<(i32,)>>::call_once - shim(vtable) @@ non_generic_closures-cgu.0[Internal]
26-
//~ MONO_ITEM fn std::ptr::drop_in_place::<{closure@TEST_PATH:27:13: 27:21}> - shim(None) @@ non_generic_closures-cgu.0[Internal]
25+
//~ MONO_ITEM fn <{closure@TEST_PATH:28:13: 28:21} as std::ops::FnOnce<(i32,)>>::call_once - shim @@ non_generic_closures-cgu.0[Internal]
26+
//~ MONO_ITEM fn <{closure@TEST_PATH:28:13: 28:21} as std::ops::FnOnce<(i32,)>>::call_once - shim(vtable) @@ non_generic_closures-cgu.0[Internal]
27+
//~ MONO_ITEM fn std::ptr::drop_in_place::<{closure@TEST_PATH:28:13: 28:21}> - shim(None) @@ non_generic_closures-cgu.0[Internal]
2728
let f = |a: i32| {
2829
let _ = a + 2;
2930
};

0 commit comments

Comments
 (0)