mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Ensure we codegen and don't internalize the entrypoint
This commit is contained in:
@@ -143,10 +143,8 @@ pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
|
||||
};
|
||||
|
||||
// Similarly, the executable entrypoint must be instantiated exactly once.
|
||||
if let Some((entry_def_id, _)) = tcx.entry_fn(()) {
|
||||
if instance.def_id() == entry_def_id {
|
||||
return InstantiationMode::GloballyShared { may_conflict: false };
|
||||
}
|
||||
if tcx.is_entrypoint(instance.def_id()) {
|
||||
return InstantiationMode::GloballyShared { may_conflict: false };
|
||||
}
|
||||
|
||||
// If the function is #[naked] or contains any other attribute that requires exactly-once
|
||||
|
||||
@@ -3402,6 +3402,20 @@ pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
|
||||
pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
|
||||
self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
|
||||
}
|
||||
|
||||
/// Whether this def is one of the special bin crate entrypoint functions that must have a
|
||||
/// monomorphization and also not be internalized in the bin crate.
|
||||
pub fn is_entrypoint(self, def_id: DefId) -> bool {
|
||||
if self.is_lang_item(def_id, LangItem::Start) {
|
||||
return true;
|
||||
}
|
||||
if let Some((entry_def_id, _)) = self.entry_fn(())
|
||||
&& entry_def_id == def_id
|
||||
{
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Parameter attributes that can only be determined by examining the body of a function instead
|
||||
|
||||
@@ -1582,6 +1582,15 @@ fn push_extra_entry_roots(&mut self) {
|
||||
return;
|
||||
};
|
||||
|
||||
let main_instance = Instance::mono(self.tcx, main_def_id);
|
||||
if self.tcx.should_codegen_locally(main_instance) {
|
||||
self.output.push(create_fn_mono_item(
|
||||
self.tcx,
|
||||
main_instance,
|
||||
self.tcx.def_span(main_def_id),
|
||||
));
|
||||
}
|
||||
|
||||
let Some(start_def_id) = self.tcx.lang_items().start_fn() else {
|
||||
self.tcx.dcx().emit_fatal(errors::StartNotFound);
|
||||
};
|
||||
|
||||
@@ -223,11 +223,7 @@ fn place_mono_items<'tcx, I>(cx: &PartitioningCx<'_, 'tcx>, mono_items: I) -> Pl
|
||||
// So even if its mode is LocalCopy, we need to treat it like a root.
|
||||
match mono_item.instantiation_mode(cx.tcx) {
|
||||
InstantiationMode::GloballyShared { .. } => {}
|
||||
InstantiationMode::LocalCopy => {
|
||||
if !cx.tcx.is_lang_item(mono_item.def_id(), LangItem::Start) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
InstantiationMode::LocalCopy => continue,
|
||||
}
|
||||
|
||||
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
|
||||
@@ -821,10 +817,9 @@ fn mono_item_visibility<'tcx>(
|
||||
| InstanceKind::FnPtrAddrShim(..) => return Visibility::Hidden,
|
||||
};
|
||||
|
||||
// The `start_fn` lang item is actually a monomorphized instance of a
|
||||
// function in the standard library, used for the `main` function. We don't
|
||||
// want to export it so we tag it with `Hidden` visibility but this symbol
|
||||
// is only referenced from the actual `main` symbol which we unfortunately
|
||||
// Both the `start_fn` lang item and `main` itself should not be exported,
|
||||
// so we give them with `Hidden` visibility but these symbols are
|
||||
// only referenced from the actual `main` symbol which we unfortunately
|
||||
// don't know anything about during partitioning/collection. As a result we
|
||||
// forcibly keep this symbol out of the `internalization_candidates` set.
|
||||
//
|
||||
@@ -834,7 +829,7 @@ fn mono_item_visibility<'tcx>(
|
||||
// from the `main` symbol we'll generate later.
|
||||
//
|
||||
// This may be fixable with a new `InstanceKind` perhaps? Unsure!
|
||||
if tcx.is_lang_item(def_id, LangItem::Start) {
|
||||
if tcx.is_entrypoint(def_id) {
|
||||
*can_be_internalized = false;
|
||||
return Visibility::Hidden;
|
||||
}
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
pub fn boilerplate() {}
|
||||
|
||||
#[inline]
|
||||
pub fn local_codegen() {}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
//@ run-pass
|
||||
//@ aux-build:main_functions.rs
|
||||
//@ compile-flags: -Ccodegen-units=1024
|
||||
|
||||
// This is a regression test for https://github.com/rust-lang/rust/issues/144052.
|
||||
// Entrypoint functions call each other in ways that CGU partitioning doesn't know about. So there
|
||||
// is a special check to not internalize any of them. But internalizing them can be okay if there
|
||||
// are few enough CGUs, so we use a lot of CGUs in this test to hit the bad case.
|
||||
|
||||
extern crate main_functions;
|
||||
pub use main_functions::local_codegen as main;
|
||||
Reference in New Issue
Block a user