diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2019-09-23 14:01:06 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2019-09-23 14:01:06 -0700 |
| commit | f00c6346b42d2a3091752166cd86aa2d69112dcc (patch) | |
| tree | 42d2ae6f70a44448023661230e71a551485dca69 | |
| parent | 50c57d8c80b1fab4c1e9087756fb9fae396d5218 (diff) | |
| download | rust-f00c6346b42d2a3091752166cd86aa2d69112dcc.tar.gz rust-f00c6346b42d2a3091752166cd86aa2d69112dcc.zip | |
Allow using upstream generics in a dylib crate type
... just don't export them!
| -rw-r--r-- | src/librustc_codegen_ssa/back/linker.rs | 22 | ||||
| -rw-r--r-- | 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 940a9a72bf6..ff87f0b1547 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<String> { 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 f18a98ffea7..0bc53dbde5f 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)| { |
