Skip to content

Commit e559172

Browse files
committed
Fix cases where std accidentally relied on inline(never)
1 parent 2b399b5 commit e559172

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

Diff for: compiler/rustc_mir_transform/src/cross_crate_inline.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
2222
return false;
2323
}
2424

25+
// This just reproduces the logic from Instance::requires_inline.
26+
match tcx.def_kind(def_id) {
27+
DefKind::Ctor(..) | DefKind::Closure => return true,
28+
DefKind::Fn | DefKind::AssocFn => {}
29+
_ => return false,
30+
}
31+
32+
// From this point on, it is valid to return true or false.
33+
if tcx.sess.opts.unstable_opts.cross_crate_inline_threshold == InliningThreshold::Always {
34+
return true;
35+
}
36+
2537
// Obey source annotations first; this is important because it means we can use
2638
// #[inline(never)] to force code generation.
2739
match codegen_fn_attrs.inline {
@@ -30,13 +42,6 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
3042
_ => {}
3143
}
3244

33-
// This just reproduces the logic from Instance::requires_inline.
34-
match tcx.def_kind(def_id) {
35-
DefKind::Ctor(..) | DefKind::Closure => return true,
36-
DefKind::Fn | DefKind::AssocFn => {}
37-
_ => return false,
38-
}
39-
4045
// Don't do any inference when incremental compilation is enabled; the additional inlining that
4146
// inference permits also creates more work for small edits.
4247
if tcx.sess.opts.incremental.is_some() {

Diff for: compiler/rustc_monomorphize/src/collector.rs

+16
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ use rustc_middle::mir::visit::Visitor as MirVisitor;
176176
use rustc_middle::mir::{self, Location};
177177
use rustc_middle::query::TyCtxtAt;
178178
use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
179+
use rustc_middle::ty::layout::ValidityRequirement;
179180
use rustc_middle::ty::print::with_no_trimmed_paths;
180181
use rustc_middle::ty::{
181182
self, AssocKind, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable,
@@ -923,6 +924,21 @@ fn visit_instance_use<'tcx>(
923924
return;
924925
}
925926

927+
// The intrinsics assert_inhabited, assert_zero_valid, and assert_mem_uninitialized_valid will
928+
// be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any
929+
// of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to
930+
// codegen a call to that function without generating code for the function itself.
931+
if let ty::InstanceDef::Intrinsic(def_id) = instance.def {
932+
let name = tcx.item_name(def_id);
933+
if let Some(_requirement) = ValidityRequirement::from_intrinsic(name) {
934+
let def_id = tcx.lang_items().get(LangItem::PanicNounwind).unwrap();
935+
let panic_instance = Instance::mono(tcx, def_id);
936+
if should_codegen_locally(tcx, &panic_instance) {
937+
output.push(create_fn_mono_item(tcx, panic_instance, source));
938+
}
939+
}
940+
}
941+
926942
match instance.def {
927943
ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(_) => {
928944
if !is_direct_call {

Diff for: compiler/rustc_monomorphize/src/partitioning.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,17 @@ where
212212
let cgu_name_cache = &mut FxHashMap::default();
213213

214214
for mono_item in mono_items {
215-
// Handle only root items directly here. Inlined items are handled at
216-
// the bottom of the loop based on reachability.
215+
// Handle only root (GloballyShared) items directly here. Inlined (LocalCopy) items
216+
// are handled at the bottom of the loop based on reachability, with one exception.
217+
// The #[lang = "start"] item is the program entrypoint, so there are no calls to it in MIR.
218+
// So even if its mode is LocalCopy, we need to treat it like a root.
217219
match mono_item.instantiation_mode(cx.tcx) {
218220
InstantiationMode::GloballyShared { .. } => {}
219-
InstantiationMode::LocalCopy => continue,
221+
InstantiationMode::LocalCopy => {
222+
if Some(mono_item.def_id()) != cx.tcx.lang_items().start_fn() {
223+
continue;
224+
}
225+
}
220226
}
221227

222228
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);

Diff for: library/std/src/rt.rs

-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ fn lang_start_internal(
155155
}
156156

157157
#[cfg(not(test))]
158-
#[inline(never)]
159158
#[lang = "start"]
160159
fn lang_start<T: crate::process::Termination + 'static>(
161160
main: fn() -> T,

0 commit comments

Comments
 (0)