summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_monomorphize
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_monomorphize
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_monomorphize')
-rw-r--r--compiler/rustc_monomorphize/messages.ftl (renamed from compiler/rustc_monomorphize/locales/en-US.ftl)0
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs98
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs2
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/default.rs48
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/merging.rs2
-rw-r--r--compiler/rustc_monomorphize/src/partitioning/mod.rs4
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs9
7 files changed, 106 insertions, 57 deletions
diff --git a/compiler/rustc_monomorphize/locales/en-US.ftl b/compiler/rustc_monomorphize/messages.ftl
index 6cea6a603..6cea6a603 100644
--- a/compiler/rustc_monomorphize/locales/en-US.ftl
+++ b/compiler/rustc_monomorphize/messages.ftl
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 45e659eab..7bcff7e07 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -174,7 +174,7 @@
//! regardless of whether it is actually needed or not.
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::sync::{par_for_each_in, MTLock, MTRef};
+use rustc_data_structures::sync::{par_for_each_in, MTLock, MTLockRef};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
@@ -190,7 +190,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::query::TyCtxtAt;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::{
- self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, VtblEntry,
+ self, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
+ VtblEntry,
};
use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext};
use rustc_session::config::EntryFnType;
@@ -340,8 +341,8 @@ pub fn collect_crate_mono_items(
let recursion_limit = tcx.recursion_limit();
{
- let visited: MTRef<'_, _> = &mut visited;
- let inlining_map: MTRef<'_, _> = &mut inlining_map;
+ let visited: MTLockRef<'_, _> = &mut visited;
+ let inlining_map: MTLockRef<'_, _> = &mut inlining_map;
tcx.sess.time("monomorphization_collector_graph_walk", || {
par_for_each_in(roots, |root| {
@@ -406,10 +407,10 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<
fn collect_items_rec<'tcx>(
tcx: TyCtxt<'tcx>,
starting_point: Spanned<MonoItem<'tcx>>,
- visited: MTRef<'_, MTLock<FxHashSet<MonoItem<'tcx>>>>,
+ visited: MTLockRef<'_, FxHashSet<MonoItem<'tcx>>>,
recursion_depths: &mut DefIdMap<usize>,
recursion_limit: Limit,
- inlining_map: MTRef<'_, MTLock<InliningMap<'tcx>>>,
+ inlining_map: MTLockRef<'_, InliningMap<'tcx>>,
) {
if !visited.lock_mut().insert(starting_point.node) {
// We've been here already, no need to search again.
@@ -462,6 +463,16 @@ fn collect_items_rec<'tcx>(
collect_miri(tcx, id, &mut neighbors);
}
}
+
+ if tcx.needs_thread_local_shim(def_id) {
+ neighbors.push(respan(
+ starting_point.span,
+ MonoItem::Fn(Instance {
+ def: InstanceDef::ThreadLocalShim(def_id),
+ substs: InternalSubsts::empty(),
+ }),
+ ));
+ }
}
MonoItem::Fn(instance) => {
// Sanity check whether this ended up being collected accidentally
@@ -640,8 +651,8 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
let span = tcx.def_span(instance.def_id());
let mut path = PathBuf::new();
- let was_written = if written_to_path.is_some() {
- path = written_to_path.unwrap();
+ let was_written = if let Some(path2) = written_to_path {
+ path = path2;
Some(())
} else {
None
@@ -808,8 +819,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
let callee_ty = self.monomorphize(callee_ty);
visit_fn_use(self.tcx, callee_ty, true, source, &mut self.output)
}
- mir::TerminatorKind::Drop { ref place, .. }
- | mir::TerminatorKind::DropAndReplace { ref place, .. } => {
+ mir::TerminatorKind::Drop { ref place, .. } => {
let ty = place.ty(self.body, self.tcx).ty;
let ty = self.monomorphize(ty);
visit_drop_use(self.tcx, ty, true, source, self.output);
@@ -842,7 +852,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
self.output.push(create_fn_mono_item(tcx, instance, source));
}
}
- mir::TerminatorKind::Abort { .. } => {
+ mir::TerminatorKind::Terminate { .. } => {
let instance = Instance::mono(
tcx,
tcx.require_lang_item(LangItem::PanicCannotUnwind, Some(source)),
@@ -862,6 +872,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
| mir::TerminatorKind::FalseUnwind { .. } => bug!(),
}
+ if let Some(mir::UnwindAction::Terminate) = terminator.unwind() {
+ let instance = Instance::mono(
+ tcx,
+ tcx.require_lang_item(LangItem::PanicCannotUnwind, Some(source)),
+ );
+ if should_codegen_locally(tcx, &instance) {
+ self.output.push(create_fn_mono_item(tcx, instance, source));
+ }
+ }
+
self.super_terminator(terminator, location);
}
@@ -963,6 +983,9 @@ fn visit_instance_use<'tcx>(
bug!("{:?} being reified", instance);
}
}
+ ty::InstanceDef::ThreadLocalShim(..) => {
+ bug!("{:?} being reified", instance);
+ }
ty::InstanceDef::DropGlue(_, None) => {
// Don't need to emit noop drop glue if we are calling directly.
if !is_direct_call {
@@ -975,7 +998,8 @@ fn visit_instance_use<'tcx>(
| ty::InstanceDef::ClosureOnceShim { .. }
| ty::InstanceDef::Item(..)
| ty::InstanceDef::FnPtrShim(..)
- | ty::InstanceDef::CloneShim(..) => {
+ | ty::InstanceDef::CloneShim(..)
+ | ty::InstanceDef::FnPtrAddrShim(..) => {
output.push(create_fn_mono_item(tcx, instance, source));
}
}
@@ -1105,7 +1129,8 @@ fn find_vtable_types_for_unsizing<'tcx>(
let target_fields = &target_adt_def.non_enum_variant().fields;
assert!(
- coerce_index < source_fields.len() && source_fields.len() == target_fields.len()
+ coerce_index.index() < source_fields.len()
+ && source_fields.len() == target_fields.len()
);
find_vtable_types_for_unsizing(
@@ -1210,11 +1235,9 @@ impl<'v> RootCollector<'_, 'v> {
self.output.push(dummy_spanned(MonoItem::GlobalAsm(id)));
}
DefKind::Static(..) => {
- debug!(
- "RootCollector: ItemKind::Static({})",
- self.tcx.def_path_str(id.owner_id.to_def_id())
- );
- self.output.push(dummy_spanned(MonoItem::Static(id.owner_id.to_def_id())));
+ let def_id = id.owner_id.to_def_id();
+ debug!("RootCollector: ItemKind::Static({})", self.tcx.def_path_str(def_id));
+ self.output.push(dummy_spanned(MonoItem::Static(def_id)));
}
DefKind::Const => {
// const items only generate mono items if they are
@@ -1331,7 +1354,35 @@ fn create_mono_items_for_default_impls<'tcx>(
return;
};
- let trait_ref = trait_ref.subst_identity();
+ // Lifetimes never affect trait selection, so we are allowed to eagerly
+ // instantiate an instance of an impl method if the impl (and method,
+ // which we check below) is only parameterized over lifetime. In that case,
+ // we use the ReErased, which has no lifetime information associated with
+ // it, to validate whether or not the impl is legal to instantiate at all.
+ let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind {
+ GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
+ GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
+ unreachable!(
+ "`own_requires_monomorphization` check means that \
+ we should have no type/const params"
+ )
+ }
+ };
+ let impl_substs = InternalSubsts::for_item(tcx, item.owner_id.to_def_id(), only_region_params);
+ let trait_ref = trait_ref.subst(tcx, impl_substs);
+
+ // Unlike 'lazy' monomorphization that begins by collecting items transitively
+ // called by `main` or other global items, when eagerly monomorphizing impl
+ // items, we never actually check that the predicates of this impl are satisfied
+ // in a empty reveal-all param env (i.e. with no assumptions).
+ //
+ // Even though this impl has no type or const substitutions, because we don't
+ // consider higher-ranked predicates such as `for<'a> &'a mut [u8]: Copy` to
+ // be trivially false. We must now check that the impl has no impossible-to-satisfy
+ // predicates.
+ if tcx.subst_and_check_impossible_predicates((item.owner_id.to_def_id(), impl_substs)) {
+ return;
+ }
let param_env = ty::ParamEnv::reveal_all();
let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref);
@@ -1345,12 +1396,9 @@ fn create_mono_items_for_default_impls<'tcx>(
continue;
}
- let substs = InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind {
- GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
- GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
- trait_ref.substs[param.index as usize]
- }
- });
+ // As mentioned above, the method is legal to eagerly instantiate if it
+ // only has lifetime substitutions. This is validated by
+ let substs = trait_ref.substs.extend_to(tcx, method.def_id, only_region_params);
let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, substs);
let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP);
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index f6b791f29..5000fb719 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -23,7 +23,7 @@ mod partitioning;
mod polymorphize;
mod util;
-fluent_messages! { "../locales/en-US.ftl" }
+fluent_messages! { "../messages.ftl" }
fn custom_coerce_unsize_info<'tcx>(
tcx: TyCtxtAt<'tcx>,
diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs
index 2c56edd89..482b78d42 100644
--- a/compiler/rustc_monomorphize/src/partitioning/default.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/default.rs
@@ -9,7 +9,7 @@ use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility};
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
use rustc_middle::ty::print::characteristic_def_id_of_type;
-use rustc_middle::ty::{self, visit::TypeVisitableExt, DefIdTree, InstanceDef, TyCtxt};
+use rustc_middle::ty::{self, visit::TypeVisitableExt, InstanceDef, TyCtxt};
use rustc_span::symbol::Symbol;
use super::PartitioningCx;
@@ -89,10 +89,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning {
}
PreInliningPartitioning {
- codegen_units: codegen_units
- .into_iter()
- .map(|(_, codegen_unit)| codegen_unit)
- .collect(),
+ codegen_units: codegen_units.into_values().map(|codegen_unit| codegen_unit).collect(),
roots,
internalization_candidates,
}
@@ -278,7 +275,9 @@ fn characteristic_def_id_of_mono_item<'tcx>(
| ty::InstanceDef::Intrinsic(..)
| ty::InstanceDef::DropGlue(..)
| ty::InstanceDef::Virtual(..)
- | ty::InstanceDef::CloneShim(..) => return None,
+ | ty::InstanceDef::CloneShim(..)
+ | ty::InstanceDef::ThreadLocalShim(..)
+ | ty::InstanceDef::FnPtrAddrShim(..) => return None,
};
// If this is a method, we want to put it into the same module as
@@ -391,6 +390,19 @@ fn mono_item_linkage_and_visibility<'tcx>(
type CguNameCache = FxHashMap<(DefId, bool), Symbol>;
+fn static_visibility<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ can_be_internalized: &mut bool,
+ def_id: DefId,
+) -> Visibility {
+ if tcx.is_reachable_non_generic(def_id) {
+ *can_be_internalized = false;
+ default_visibility(tcx, def_id, false)
+ } else {
+ Visibility::Hidden
+ }
+}
+
fn mono_item_visibility<'tcx>(
tcx: TyCtxt<'tcx>,
mono_item: &MonoItem<'tcx>,
@@ -402,21 +414,9 @@ fn mono_item_visibility<'tcx>(
MonoItem::Fn(instance) => instance,
// Misc handling for generics and such, but otherwise:
- MonoItem::Static(def_id) => {
- return if tcx.is_reachable_non_generic(*def_id) {
- *can_be_internalized = false;
- default_visibility(tcx, *def_id, false)
- } else {
- Visibility::Hidden
- };
- }
+ MonoItem::Static(def_id) => return static_visibility(tcx, can_be_internalized, *def_id),
MonoItem::GlobalAsm(item_id) => {
- return if tcx.is_reachable_non_generic(item_id.owner_id) {
- *can_be_internalized = false;
- default_visibility(tcx, item_id.owner_id.to_def_id(), false)
- } else {
- Visibility::Hidden
- };
+ return static_visibility(tcx, can_be_internalized, item_id.owner_id.to_def_id());
}
};
@@ -424,6 +424,11 @@ fn mono_item_visibility<'tcx>(
InstanceDef::Item(def) => def.did,
InstanceDef::DropGlue(def_id, Some(_)) => def_id,
+ // We match the visiblity of statics here
+ InstanceDef::ThreadLocalShim(def_id) => {
+ return static_visibility(tcx, can_be_internalized, def_id);
+ }
+
// These are all compiler glue and such, never exported, always hidden.
InstanceDef::VTableShim(..)
| InstanceDef::ReifyShim(..)
@@ -432,7 +437,8 @@ fn mono_item_visibility<'tcx>(
| InstanceDef::Intrinsic(..)
| InstanceDef::ClosureOnceShim { .. }
| InstanceDef::DropGlue(..)
- | InstanceDef::CloneShim(..) => return Visibility::Hidden,
+ | InstanceDef::CloneShim(..)
+ | InstanceDef::FnPtrAddrShim(..) => return Visibility::Hidden,
};
// The `start_fn` lang item is actually a monomorphized instance of a
diff --git a/compiler/rustc_monomorphize/src/partitioning/merging.rs b/compiler/rustc_monomorphize/src/partitioning/merging.rs
index 02bb8dea0..5c524a184 100644
--- a/compiler/rustc_monomorphize/src/partitioning/merging.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/merging.rs
@@ -24,7 +24,7 @@ pub fn merge_codegen_units<'tcx>(
// smallest into each other) we're sure to start off with a deterministic
// order (sorted by name). This'll mean that if two cgus have the same size
// the stable sort below will keep everything nice and deterministic.
- codegen_units.sort_by(|a, b| a.name().as_str().partial_cmp(b.name().as_str()).unwrap());
+ codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
// This map keeps track of what got merged into what.
let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs
index 524c51d88..18aa0742c 100644
--- a/compiler/rustc_monomorphize/src/partitioning/mod.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs
@@ -252,7 +252,7 @@ pub fn partition<'tcx>(
internalization_candidates: _,
} = post_inlining;
- result.sort_by(|a, b| a.name().as_str().partial_cmp(b.name().as_str()).unwrap());
+ result.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
result
}
@@ -474,7 +474,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
(tcx.arena.alloc(mono_items), codegen_units)
}
-/// Outputs stats about instantation counts and estimated size, per `MonoItem`'s
+/// Outputs stats about instantiation counts and estimated size, per `MonoItem`'s
/// def, to a file in the given output directory.
fn dump_mono_items_stats<'tcx>(
tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index b7c3dbcc0..63263a642 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -36,6 +36,8 @@ fn unused_generic_params<'tcx>(
tcx: TyCtxt<'tcx>,
instance: ty::InstanceDef<'tcx>,
) -> UnusedGenericParams {
+ assert!(instance.def_id().is_local());
+
if !tcx.sess.opts.unstable_opts.polymorphize {
// If polymorphization disabled, then all parameters are used.
return UnusedGenericParams::new_all_used();
@@ -100,13 +102,6 @@ fn should_polymorphize<'tcx>(
return false;
}
- // Polymorphization results are stored in cross-crate metadata only when there are unused
- // parameters, so assume that non-local items must have only used parameters (else this query
- // would not be invoked, and the cross-crate metadata used instead).
- if !def_id.is_local() {
- return false;
- }
-
// Foreign items have no bodies to analyze.
if tcx.is_foreign_item(def_id) {
return false;