Update a few comments about symbol visibility.
This commit is contained in:
parent
69c7f5ccbb
commit
ec55390387
@ -762,14 +762,22 @@ fn should_monomorphize_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance:
|
|||||||
-> bool {
|
-> bool {
|
||||||
debug_assert!(!def_id.is_local());
|
debug_assert!(!def_id.is_local());
|
||||||
|
|
||||||
|
// If we are not in share generics mode, we don't link to upstream
|
||||||
|
// monomorphizations but always instantiate our own internal versions
|
||||||
|
// instead.
|
||||||
if !tcx.share_generics() {
|
if !tcx.share_generics() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this instance has no type parameters, it cannot be a shared
|
||||||
|
// monomorphization. Non-generic instances are already handled above
|
||||||
|
// by `is_reachable_non_generic()`
|
||||||
if substs.types().next().is_none() {
|
if substs.types().next().is_none() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Take a look at the available monomorphizations listed in the metadata
|
||||||
|
// of upstream crates.
|
||||||
tcx.upstream_monomorphizations_for(def_id)
|
tcx.upstream_monomorphizations_for(def_id)
|
||||||
.map(|set| set.contains_key(substs))
|
.map(|set| set.contains_key(substs))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
|
@ -301,6 +301,11 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
let mut codegen_units = FxHashMap();
|
let mut codegen_units = FxHashMap();
|
||||||
let is_incremental_build = tcx.sess.opts.incremental.is_some();
|
let is_incremental_build = tcx.sess.opts.incremental.is_some();
|
||||||
let mut internalization_candidates = FxHashSet();
|
let mut internalization_candidates = FxHashSet();
|
||||||
|
|
||||||
|
// Determine if monomorphizations instantiated in this crate will be made
|
||||||
|
// available to downstream crates. This depends on whether we are in
|
||||||
|
// share-generics mode and whether the current crate can even have
|
||||||
|
// downstream crates.
|
||||||
let export_generics = tcx.share_generics() &&
|
let export_generics = tcx.share_generics() &&
|
||||||
tcx.local_crate_exports_generics();
|
tcx.local_crate_exports_generics();
|
||||||
|
|
||||||
|
@ -118,39 +118,31 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||||||
// This is sort of subtle. Inside our codegen unit we started off
|
// This is sort of subtle. Inside our codegen unit we started off
|
||||||
// compilation by predefining all our own `TransItem` instances. That
|
// compilation by predefining all our own `TransItem` instances. That
|
||||||
// is, everything we're translating ourselves is already defined. That
|
// is, everything we're translating ourselves is already defined. That
|
||||||
// means that anything we're actually translating ourselves will have
|
// means that anything we're actually translating in this codegen unit
|
||||||
// hit the above branch in `get_declared_value`. As a result, we're
|
// will have hit the above branch in `get_declared_value`. As a result,
|
||||||
// guaranteed here that we're declaring a symbol that won't get defined,
|
// we're guaranteed here that we're declaring a symbol that won't get
|
||||||
// or in other words we're referencing a foreign value.
|
// defined, or in other words we're referencing a value from another
|
||||||
|
// codegen unit or even another crate.
|
||||||
//
|
//
|
||||||
// So because this is a foreign value we blanket apply an external
|
// So because this is a foreign value we blanket apply an external
|
||||||
// linkage directive because it's coming from a different object file.
|
// linkage directive because it's coming from a different object file.
|
||||||
// The visibility here is where it gets tricky. This symbol could be
|
// The visibility here is where it gets tricky. This symbol could be
|
||||||
// referencing some foreign crate or foreign library (an `extern`
|
// referencing some foreign crate or foreign library (an `extern`
|
||||||
// block) in which case we want to leave the default visibility. We may
|
// block) in which case we want to leave the default visibility. We may
|
||||||
// also, though, have multiple codegen units.
|
// also, though, have multiple codegen units. It could be a
|
||||||
//
|
// monomorphization, in which case its expected visibility depends on
|
||||||
// In the situation of multiple codegen units this function may be
|
// whether we are sharing generics or not. The important thing here is
|
||||||
// referencing a function from another codegen unit. If we're
|
// that the visibility we apply to the declaration is the same one that
|
||||||
// indeed referencing a symbol in another codegen unit then we're in one
|
// has been applied to the definition (wherever that definition may be).
|
||||||
// of two cases:
|
|
||||||
//
|
|
||||||
// * This is a symbol defined in a foreign crate and we're just
|
|
||||||
// monomorphizing in another codegen unit. In this case this symbols
|
|
||||||
// is for sure not exported, so both codegen units will be using
|
|
||||||
// hidden visibility. Hence, we apply a hidden visibility here.
|
|
||||||
//
|
|
||||||
// * This is a symbol defined in our local crate. If the symbol in the
|
|
||||||
// other codegen unit is also not exported then like with the foreign
|
|
||||||
// case we apply a hidden visibility. If the symbol is exported from
|
|
||||||
// the foreign object file, however, then we leave this at the
|
|
||||||
// default visibility as we'll just import it naturally.
|
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
|
||||||
|
|
||||||
let is_generic = instance.substs.types().next().is_some();
|
let is_generic = instance.substs.types().next().is_some();
|
||||||
|
|
||||||
if is_generic {
|
if is_generic {
|
||||||
|
// This is a monomorphization. Its expected visibility depends
|
||||||
|
// on whether we are in share-generics mode.
|
||||||
|
|
||||||
if cx.tcx.share_generics() {
|
if cx.tcx.share_generics() {
|
||||||
// We are in share_generics mode.
|
// We are in share_generics mode.
|
||||||
|
|
||||||
@ -158,19 +150,25 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||||||
// This is a definition from the current crate. If the
|
// This is a definition from the current crate. If the
|
||||||
// definition is unreachable for downstream crates or
|
// definition is unreachable for downstream crates or
|
||||||
// the current crate does not re-export generics, the
|
// the current crate does not re-export generics, the
|
||||||
// instance has been hidden
|
// definition of the instance will have been declared
|
||||||
|
// as `hidden`.
|
||||||
if cx.tcx.is_unreachable_local_definition(instance_def_id) ||
|
if cx.tcx.is_unreachable_local_definition(instance_def_id) ||
|
||||||
!cx.tcx.local_crate_exports_generics() {
|
!cx.tcx.local_crate_exports_generics() {
|
||||||
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
|
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// This is a monomorphization of a generic function
|
||||||
|
// defined in an upstream crate.
|
||||||
if cx.tcx.upstream_monomorphizations_for(instance_def_id)
|
if cx.tcx.upstream_monomorphizations_for(instance_def_id)
|
||||||
.map(|set| set.contains_key(instance.substs))
|
.map(|set| set.contains_key(instance.substs))
|
||||||
.unwrap_or(false) {
|
.unwrap_or(false) {
|
||||||
// This is instantiated in another crate. It cannot be hidden
|
// This is instantiated in another crate. It cannot
|
||||||
|
// be `hidden`.
|
||||||
} else {
|
} else {
|
||||||
// This is a local instantiation of an upstream definition.
|
// This is a local instantiation of an upstream definition.
|
||||||
// If the current crate does not re-export it, it is hidden.
|
// If the current crate does not re-export it
|
||||||
|
// (because it is a C library or an executable), it
|
||||||
|
// will have been declared `hidden`.
|
||||||
if !cx.tcx.local_crate_exports_generics() {
|
if !cx.tcx.local_crate_exports_generics() {
|
||||||
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
|
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user