From f00c6346b42d2a3091752166cd86aa2d69112dcc Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 23 Sep 2019 14:01:06 -0700 Subject: [PATCH] Allow using upstream generics in a dylib crate type ... just don't export them! --- src/librustc_codegen_ssa/back/linker.rs | 22 ++++++++++++++++++++-- src/librustc_metadata/cstore_impl.rs | 13 ++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 940a9a72bf6d4..ff87f0b1547ce 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -14,6 +14,7 @@ use rustc::middle::dependency_format::Linkage; use rustc::session::Session; use rustc::session::config::{self, CrateType, OptLevel, DebugInfo, LinkerPluginLto, Lto}; +use rustc::middle::exported_symbols::ExportedSymbol; use rustc::ty::TyCtxt; use rustc_target::spec::{LinkerFlavor, LldFlavor}; use rustc_serialize::{json, Encoder}; @@ -1107,9 +1108,26 @@ fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec { if *dep_format == Linkage::Static { // ... we add its symbol list to our export list. for &(symbol, level) in tcx.exported_symbols(cnum).iter() { - if level.is_below_threshold(export_threshold) { - symbols.push(symbol.symbol_name(tcx).to_string()); + if !level.is_below_threshold(export_threshold) { + continue; } + + // Do not export generic symbols from upstream crates in linked + // artifact (notably the `dylib` crate type). The main reason + // for this is that `symbol_name` is actually wrong for generic + // symbols because it guesses the name we'd give them locally + // rather than the name it has upstream (depending on + // `share_generics` settings and such). + // + // To fix that issue we just say that linked artifacts, aka + // `dylib`s, never export generic symbols and they aren't + // available to downstream crates. (the not available part is + // handled elsewhere). + if let ExportedSymbol::Generic(..) = symbol { + continue; + } + + symbols.push(symbol.symbol_name(tcx).to_string()); } } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index f18a98ffea7cd..0bc53dbde5f8a 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -11,7 +11,6 @@ use rustc::middle::cstore::{CrateStore, DepKind, use rustc::middle::exported_symbols::ExportedSymbol; use rustc::middle::stability::DeprecationEntry; use rustc::middle::dependency_format::Linkage; -use rustc::session::config::CrateType; use rustc::hir::def; use rustc::hir; use rustc::session::{CrateDisambiguator, Session}; @@ -246,13 +245,13 @@ provide! { <'tcx> tcx, def_id, other, cdata, // When linked into a dylib crates don't export their generic symbols, // so if that's happening then we can't load upstream monomorphizations - // from this crate. As a result, if we're creating a dylib or this crate - // is being included from a different dynamic library, then we filter - // out all `Generic` symbols here. + // from this crate. let formats = tcx.dependency_formats(LOCAL_CRATE); - let remove_generics = formats.iter().any(|(ty, list)| { - *ty == CrateType::Dylib || - list.get(def_id.krate.as_usize() - 1) == Some(&Linkage::IncludedFromDylib) + let remove_generics = formats.iter().any(|(_ty, list)| { + match list.get(def_id.krate.as_usize() - 1) { + Some(Linkage::IncludedFromDylib) | Some(Linkage::Dynamic) => true, + _ => false, + } }); if remove_generics { syms.retain(|(sym, _threshold)| {