about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2019-09-23 14:01:06 -0700
committerAlex Crichton <alex@alexcrichton.com>2019-09-23 14:01:06 -0700
commitf00c6346b42d2a3091752166cd86aa2d69112dcc (patch)
tree42d2ae6f70a44448023661230e71a551485dca69
parent50c57d8c80b1fab4c1e9087756fb9fae396d5218 (diff)
downloadrust-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.rs22
-rw-r--r--src/librustc_metadata/cstore_impl.rs13
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)| {