diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index f3232a0e15d9..416054d85fdb 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -225,8 +225,8 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion}; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::print::{shrunk_instance_name, with_no_trimmed_paths}; use rustc_middle::ty::{ - self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Ty, TyCtxt, TypeFoldable, - TypeVisitableExt, VtblEntry, + self, GenericArgs, GenericParamDefKind, Instance, InstanceKind, Interner, Ty, TyCtxt, + TypeFoldable, TypeVisitableExt, VtblEntry, }; use rustc_middle::util::Providers; use rustc_middle::{bug, span_bug}; @@ -965,7 +965,7 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxtAt<'tcx>, instance: Instance<'tcx>) - { // `#[rustc_force_inline]` items should never be codegened. This should be caught by // the MIR validator. - return false; + tcx.delay_bug("attempt to codegen `#[rustc_force_inline]` item"); } if def_id.is_local() { @@ -1462,7 +1462,9 @@ impl<'v> RootCollector<'_, 'v> { fn is_root(&self, def_id: LocalDefId) -> bool { !self.tcx.generics_of(def_id).requires_monomorphization(self.tcx) && match self.strategy { - MonoItemCollectionStrategy::Eager => true, + MonoItemCollectionStrategy::Eager => { + !matches!(self.tcx.codegen_fn_attrs(def_id).inline, InlineAttr::Force { .. }) + } MonoItemCollectionStrategy::Lazy => { self.entry_fn.and_then(|(id, _)| id.as_local()) == Some(def_id) || self.tcx.is_reachable_non_generic(def_id) diff --git a/tests/mir-opt/inline/forced_dead_code.caller.ForceInline.panic-abort.diff b/tests/mir-opt/inline/forced_dead_code.caller.ForceInline.panic-abort.diff new file mode 100644 index 000000000000..f894f06e5a0a --- /dev/null +++ b/tests/mir-opt/inline/forced_dead_code.caller.ForceInline.panic-abort.diff @@ -0,0 +1,21 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> () { + let mut _0: (); + let _1: (); ++ scope 1 (inlined callee_forced) { ++ } + + bb0: { + StorageLive(_1); +- _1 = callee_forced() -> [return: bb1, unwind unreachable]; +- } +- +- bb1: { + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_dead_code.caller.ForceInline.panic-unwind.diff b/tests/mir-opt/inline/forced_dead_code.caller.ForceInline.panic-unwind.diff new file mode 100644 index 000000000000..7b70fd665666 --- /dev/null +++ b/tests/mir-opt/inline/forced_dead_code.caller.ForceInline.panic-unwind.diff @@ -0,0 +1,21 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> () { + let mut _0: (); + let _1: (); ++ scope 1 (inlined callee_forced) { ++ } + + bb0: { + StorageLive(_1); +- _1 = callee_forced() -> [return: bb1, unwind continue]; +- } +- +- bb1: { + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_dead_code.rs b/tests/mir-opt/inline/forced_dead_code.rs new file mode 100644 index 000000000000..832272cde7f0 --- /dev/null +++ b/tests/mir-opt/inline/forced_dead_code.rs @@ -0,0 +1,17 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ compile-flags: -Copt-level=0 -Clink-dead-code +#![feature(rustc_attrs)] + +#[rustc_force_inline] +pub fn callee_forced() {} + +// EMIT_MIR forced_dead_code.caller.ForceInline.diff +pub fn caller() { + callee_forced(); + // CHECK-LABEL: fn caller( + // CHECK: (inlined callee_forced) +} + +fn main() { + caller(); +}