Skip to content

Commit 47ebc3d

Browse files
committed
cross crate polymorphization
1 parent ccb1eae commit 47ebc3d

File tree

4 files changed

+44
-15
lines changed

4 files changed

+44
-15
lines changed

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use std::collections::hash_map::Entry::*;
1+
use std::collections::btree_map::Entry::*;
2+
use std::collections::BTreeMap;
23

34
use rustc_ast::expand::allocator::ALLOCATOR_METHODS;
45
use rustc_data_structures::fingerprint::Fingerprint;
@@ -14,7 +15,7 @@ use rustc_middle::middle::exported_symbols::{
1415
use rustc_middle::ty::query::{ExternProviders, Providers};
1516
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
1617
use rustc_middle::ty::Instance;
17-
use rustc_middle::ty::{SymbolName, TyCtxt};
18+
use rustc_middle::ty::{self, SymbolName, TyCtxt};
1819
use rustc_session::config::CrateType;
1920
use rustc_target::spec::SanitizerSet;
2021

@@ -272,10 +273,10 @@ fn exported_symbols_provider_local(
272273
fn upstream_monomorphizations_provider(
273274
tcx: TyCtxt<'_>,
274275
(): (),
275-
) -> DefIdMap<FxHashMap<SubstsRef<'_>, CrateNum>> {
276+
) -> DefIdMap<BTreeMap<SubstsRef<'_>, CrateNum>> {
276277
let cnums = tcx.crates(());
277278

278-
let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default();
279+
let mut instances: DefIdMap<BTreeMap<_, _>> = Default::default();
279280

280281
let cnum_stable_ids: IndexVec<CrateNum, Fingerprint> = {
281282
let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO, cnums.len() + 1);
@@ -333,7 +334,7 @@ fn upstream_monomorphizations_provider(
333334
fn upstream_monomorphizations_for_provider(
334335
tcx: TyCtxt<'_>,
335336
def_id: DefId,
336-
) -> Option<&FxHashMap<SubstsRef<'_>, CrateNum>> {
337+
) -> Option<&BTreeMap<SubstsRef<'_>, CrateNum>> {
337338
debug_assert!(!def_id.is_local());
338339
tcx.upstream_monomorphizations(()).get(&def_id)
339340
}
@@ -343,7 +344,20 @@ fn upstream_drop_glue_for_provider<'tcx>(
343344
substs: SubstsRef<'tcx>,
344345
) -> Option<CrateNum> {
345346
if let Some(def_id) = tcx.lang_items().drop_in_place_fn() {
346-
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&substs).cloned())
347+
tcx.upstream_monomorphizations_for(def_id).and_then(|monos| {
348+
monos.get(&substs).cloned().or_else(|| {
349+
monos
350+
.iter()
351+
.find(|(k, _)| {
352+
tcx.is_polymorphic_parent((
353+
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
354+
k,
355+
substs,
356+
))
357+
})
358+
.map(|(_, &v)| v)
359+
})
360+
})
347361
} else {
348362
None
349363
}

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ impl MonoItemMap<'tcx> {
288288
) -> Option<Instance<'tcx>> {
289289
if instance.substs.non_erasable_generics().next().is_some() {
290290
for substs in self.item_map.get(&instance.def).into_iter().flat_map(|v| v).copied() {
291-
// FIXME(polymorphization): Deal with more complex polymorphized stuff.
292291
if substs == instance.substs
293292
|| tcx.is_polymorphic_parent((instance.def, substs, instance.substs))
294293
{

compiler/rustc_middle/src/query/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,7 +1307,7 @@ rustc_queries! {
13071307
/// added or removed in any upstream crate. Instead use the narrower
13081308
/// `upstream_monomorphizations_for`, `upstream_drop_glue_for`, or, even
13091309
/// better, `Instance::upstream_monomorphization()`.
1310-
query upstream_monomorphizations(_: ()) -> DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>> {
1310+
query upstream_monomorphizations(_: ()) -> DefIdMap<BTreeMap<SubstsRef<'tcx>, CrateNum>> {
13111311
storage(ArenaCacheSelector<'tcx>)
13121312
desc { "collecting available upstream monomorphizations" }
13131313
}
@@ -1320,7 +1320,7 @@ rustc_queries! {
13201320
/// You likely want to call `Instance::upstream_monomorphization()`
13211321
/// instead of invoking this query directly.
13221322
query upstream_monomorphizations_for(def_id: DefId)
1323-
-> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> {
1323+
-> Option<&'tcx BTreeMap<SubstsRef<'tcx>, CrateNum>> {
13241324
desc { |tcx|
13251325
"collecting available upstream monomorphizations for `{}`",
13261326
tcx.def_path_str(def_id),

compiler/rustc_middle/src/ty/instance.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,16 @@ impl<'tcx> Instance<'tcx> {
127127
self.substs.non_erasable_generics().next()?;
128128

129129
match self.def {
130-
// FIXME(polymorphization): Deal with this. Can't use
131-
// `polymorphize` as that causes cycles.
132-
InstanceDef::Item(def) => tcx
133-
.upstream_monomorphizations_for(def.did)
134-
.and_then(|monos| monos.get(&self.substs).cloned()),
130+
InstanceDef::Item(def) => {
131+
tcx.upstream_monomorphizations_for(def.did).and_then(|monos| {
132+
monos.get(&self.substs).cloned().or_else(|| {
133+
monos
134+
.iter()
135+
.find(|(k, _)| tcx.is_polymorphic_parent((self.def, k, self.substs)))
136+
.map(|(_, &v)| v)
137+
})
138+
})
139+
}
135140
InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs),
136141
_ => None,
137142
}
@@ -594,7 +599,18 @@ impl<'tcx> Instance<'tcx> {
594599
// polymorphic instances from separate crates,
595600
// and assume that we just have a mono item for this
596601
// instance in some other crate.
597-
None => self,
602+
None => match self.def {
603+
InstanceDef::Item(def) if !def.is_local() => tcx
604+
.upstream_monomorphizations_for(def.did)
605+
.and_then(|monos| {
606+
monos
607+
.iter()
608+
.find(|(k, _)| tcx.is_polymorphic_parent((self.def, k, self.substs)))
609+
.map(|(k, _)| Instance { def: self.def, substs: k })
610+
})
611+
.unwrap_or(self),
612+
_ => self,
613+
},
598614
}
599615
}
600616
}

0 commit comments

Comments
 (0)