Skip to content

Commit 9494974

Browse files
[wip] Add projection query for upstream drop-glue instances.
1 parent 98034e9 commit 9494974

File tree

7 files changed

+63
-56
lines changed

7 files changed

+63
-56
lines changed

src/librustc/query/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,11 @@ rustc_queries! {
783783
}
784784
query upstream_monomorphizations_for(_: DefId)
785785
-> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> {}
786+
787+
query upstream_drop_glue_for(substs: SubstsRef<'tcx>) -> Option<CrateNum> {
788+
desc { "available upstream drop-glue for `{:?}`", substs }
789+
no_force
790+
}
786791
}
787792

788793
Other {

src/librustc/ty/instance.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::traits;
44
use crate::ty::print::{FmtPrinter, Printer};
55
use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeFoldable};
66
use rustc_hir::def::Namespace;
7-
use rustc_hir::def_id::DefId;
7+
use rustc_hir::def_id::{CrateNum, DefId};
88
use rustc_macros::HashStable;
99
use rustc_target::spec::abi::Abi;
1010

@@ -91,6 +91,38 @@ impl<'tcx> Instance<'tcx> {
9191
let ty = tcx.type_of(self.def.def_id());
9292
tcx.subst_and_normalize_erasing_regions(self.substs, param_env, &ty)
9393
}
94+
95+
pub fn upstream_monomorphization(&self, tcx: TyCtxt<'tcx>) -> Option<CrateNum> {
96+
// If we are not in share generics mode, we don't link to upstream
97+
// monomorphizations but always instantiate our own internal versions
98+
// instead.
99+
if !tcx.sess.opts.share_generics() {
100+
return None;
101+
}
102+
103+
// If this instance has non-erasable parameters, it cannot be a shared
104+
// monomorphization. Non-generic instances are already handled above
105+
// by `is_reachable_non_generic()`.
106+
if self.substs.non_erasable_generics().next().is_none() {
107+
return None;
108+
}
109+
110+
if self.def_id().is_local() {
111+
return None;
112+
}
113+
114+
match self.def {
115+
InstanceDef::Item(def_id) => {
116+
tcx
117+
.upstream_monomorphizations_for(def_id)
118+
.and_then(|monos| monos.get(&self.substs).cloned())
119+
}
120+
InstanceDef::DropGlue(_, Some(_)) => {
121+
tcx.upstream_drop_glue_for(self.substs)
122+
}
123+
_ => None,
124+
}
125+
}
94126
}
95127

96128
impl<'tcx> InstanceDef<'tcx> {

src/librustc/ty/query/keys.rs

+9
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ impl Key for (DefId, SimplifiedType) {
116116
}
117117
}
118118

119+
impl<'tcx> Key for SubstsRef<'tcx> {
120+
fn query_crate(&self) -> CrateNum {
121+
LOCAL_CRATE
122+
}
123+
fn default_span(&self, _: TyCtxt<'_>) -> Span {
124+
DUMMY_SP
125+
}
126+
}
127+
119128
impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
120129
fn query_crate(&self) -> CrateNum {
121130
self.0.krate

src/librustc_codegen_llvm/callee.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
130130
} else {
131131
// This is a monomorphization of a generic function
132132
// defined in an upstream crate.
133-
if cx
134-
.tcx
135-
.upstream_monomorphizations_for(instance_def_id)
136-
.map(|set| set.contains_key(instance.substs))
137-
.unwrap_or(false)
138-
{
133+
if instance.upstream_monomorphization(tcx).is_some() {
139134
// This is instantiated in another crate. It cannot
140135
// be `hidden`.
141136
} else {

src/librustc_codegen_ssa/back/symbol_export.rs

+12
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,17 @@ fn upstream_monomorphizations_for_provider(
321321
tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id)
322322
}
323323

324+
fn upstream_drop_glue_for_provider<'tcx>(
325+
tcx: TyCtxt<'tcx>,
326+
substs: SubstsRef<'tcx>,
327+
) -> Option<CrateNum> {
328+
if let Some(def_id) = tcx.lang_items().drop_in_place_fn() {
329+
tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id).and_then(|monos| monos.get(&substs).cloned())
330+
} else {
331+
None
332+
}
333+
}
334+
324335
fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
325336
if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) {
326337
!tcx.reachable_set(LOCAL_CRATE).contains(&hir_id)
@@ -335,6 +346,7 @@ pub fn provide(providers: &mut Providers<'_>) {
335346
providers.exported_symbols = exported_symbols_provider_local;
336347
providers.upstream_monomorphizations = upstream_monomorphizations_provider;
337348
providers.is_unreachable_local_definition = is_unreachable_local_definition_provider;
349+
providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;
338350
}
339351

340352
pub fn provide_extern(providers: &mut Providers<'_>) {

src/librustc_codegen_utils/symbol_names.rs

+1-19
Original file line numberDiff line numberDiff line change
@@ -129,26 +129,8 @@ fn symbol_name_provider(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty::Symb
129129
//
130130
// For generics we might find re-usable upstream instances. For anything
131131
// else we rely on their being a local copy available.
132-
133132
if is_generic(instance.substs) {
134-
let def_id = instance.def_id();
135-
136-
if !def_id.is_local() && tcx.sess.opts.share_generics() {
137-
// If we are re-using a monomorphization from another crate,
138-
// we have to compute the symbol hash accordingly.
139-
let upstream_monomorphizations = tcx.upstream_monomorphizations_for(def_id);
140-
141-
upstream_monomorphizations
142-
.and_then(|monos| monos.get(&instance.substs).cloned())
143-
// If there is no instance available upstream, there'll be
144-
// one in the current crate.
145-
.unwrap_or(LOCAL_CRATE)
146-
} else {
147-
// For generic functions defined in the current crate, there
148-
// can be no upstream instances. Also, if we don't share
149-
// generics, we'll instantiate a local copy too.
150-
LOCAL_CRATE
151-
}
133+
instance.upstream_monomorphization(tcx).unwrap_or(LOCAL_CRATE)
152134
} else {
153135
// For non-generic things that need to avoid naming conflicts, we
154136
// always instantiate a copy in the local crate.

src/librustc_mir/monomorphize/collector.rs

+2-30
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,8 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx
737737
return true;
738738
}
739739

740-
if tcx.is_reachable_non_generic(def_id)
741-
|| is_available_upstream_generic(tcx, def_id, instance.substs)
740+
if tcx.is_reachable_non_generic(def_id) ||
741+
instance.upstream_monomorphization(tcx).is_some()
742742
{
743743
// We can link to the item in question, no instance needed
744744
// in this crate.
@@ -750,34 +750,6 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx
750750
}
751751

752752
return true;
753-
754-
fn is_available_upstream_generic<'tcx>(
755-
tcx: TyCtxt<'tcx>,
756-
def_id: DefId,
757-
substs: SubstsRef<'tcx>,
758-
) -> bool {
759-
debug_assert!(!def_id.is_local());
760-
761-
// If we are not in share generics mode, we don't link to upstream
762-
// monomorphizations but always instantiate our own internal versions
763-
// instead.
764-
if !tcx.sess.opts.share_generics() {
765-
return false;
766-
}
767-
768-
// If this instance has non-erasable parameters, it cannot be a shared
769-
// monomorphization. Non-generic instances are already handled above
770-
// by `is_reachable_non_generic()`.
771-
if substs.non_erasable_generics().next().is_none() {
772-
return false;
773-
}
774-
775-
// Take a look at the available monomorphizations listed in the metadata
776-
// of upstream crates.
777-
tcx.upstream_monomorphizations_for(def_id)
778-
.map(|set| set.contains_key(substs))
779-
.unwrap_or(false)
780-
}
781753
}
782754

783755
/// For a given pair of source and target type that occur in an unsizing coercion,

0 commit comments

Comments
 (0)