]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_codegen_ssa/back/linker.rs
Auto merge of #65140 - petrochenkov:disapp, r=nikomatsakis
[rust.git] / src / librustc_codegen_ssa / back / linker.rs
index de481d2262478630d74266e20b1e1342678d048e..ff87f0b1547cec36a61cb67a2780bc0adf8057dc 100644 (file)
 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};
+use syntax::symbol::Symbol;
 
 /// For all the linkers we support, and information they might
 /// need out of the shared crate context before we get rid of it.
@@ -99,13 +101,13 @@ pub fn to_linker<'a>(
 /// used to dispatch on whether a GNU-like linker (generally `ld.exe`) or an
 /// MSVC linker (e.g., `link.exe`) is being used.
 pub trait Linker {
-    fn link_dylib(&mut self, lib: &str);
-    fn link_rust_dylib(&mut self, lib: &str, path: &Path);
-    fn link_framework(&mut self, framework: &str);
-    fn link_staticlib(&mut self, lib: &str);
+    fn link_dylib(&mut self, lib: Symbol);
+    fn link_rust_dylib(&mut self, lib: Symbol, path: &Path);
+    fn link_framework(&mut self, framework: Symbol);
+    fn link_staticlib(&mut self, lib: Symbol);
     fn link_rlib(&mut self, lib: &Path);
     fn link_whole_rlib(&mut self, lib: &Path);
-    fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]);
+    fn link_whole_staticlib(&mut self, lib: Symbol, search_path: &[PathBuf]);
     fn include_path(&mut self, path: &Path);
     fn framework_path(&mut self, path: &Path);
     fn output_filename(&mut self, path: &Path);
@@ -215,9 +217,13 @@ fn push_linker_plugin_lto_args(&mut self, plugin_path: Option<&OsStr>) {
 }
 
 impl<'a> Linker for GccLinker<'a> {
-    fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg(format!("-l{}", lib)); }
-    fn link_staticlib(&mut self, lib: &str) {
-        self.hint_static(); self.cmd.arg(format!("-l{}", lib));
+    fn link_dylib(&mut self, lib: Symbol) {
+        self.hint_dynamic();
+        self.cmd.arg(format!("-l{}", lib));
+    }
+    fn link_staticlib(&mut self, lib: Symbol) {
+        self.hint_static();
+        self.cmd.arg(format!("-l{}", lib));
     }
     fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); }
     fn include_path(&mut self, path: &Path) { self.cmd.arg("-L").arg(path); }
@@ -232,14 +238,14 @@ fn link_staticlib(&mut self, lib: &str) {
     fn build_static_executable(&mut self) { self.cmd.arg("-static"); }
     fn args(&mut self, args: &[String]) { self.cmd.args(args); }
 
-    fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
+    fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
         self.hint_dynamic();
         self.cmd.arg(format!("-l{}", lib));
     }
 
-    fn link_framework(&mut self, framework: &str) {
+    fn link_framework(&mut self, framework: Symbol) {
         self.hint_dynamic();
-        self.cmd.arg("-framework").arg(framework);
+        self.cmd.arg("-framework").sym_arg(framework);
     }
 
     // Here we explicitly ask that the entire archive is included into the
@@ -248,7 +254,7 @@ fn link_framework(&mut self, framework: &str) {
     // don't otherwise explicitly reference them. This can occur for
     // libraries which are just providing bindings, libraries with generic
     // functions, etc.
-    fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]) {
+    fn link_whole_staticlib(&mut self, lib: Symbol, search_path: &[PathBuf]) {
         self.hint_static();
         let target = &self.sess.target.target;
         if !target.options.is_like_osx {
@@ -539,11 +545,11 @@ fn gc_sections(&mut self, _keep_metadata: bool) {
         }
     }
 
-    fn link_dylib(&mut self, lib: &str) {
+    fn link_dylib(&mut self, lib: Symbol) {
         self.cmd.arg(&format!("{}.lib", lib));
     }
 
-    fn link_rust_dylib(&mut self, lib: &str, path: &Path) {
+    fn link_rust_dylib(&mut self, lib: Symbol, path: &Path) {
         // When producing a dll, the MSVC linker may not actually emit a
         // `foo.lib` file if the dll doesn't actually export any symbols, so we
         // check to see if the file is there and just omit linking to it if it's
@@ -554,7 +560,7 @@ fn link_rust_dylib(&mut self, lib: &str, path: &Path) {
         }
     }
 
-    fn link_staticlib(&mut self, lib: &str) {
+    fn link_staticlib(&mut self, lib: Symbol) {
         self.cmd.arg(&format!("{}.lib", lib));
     }
 
@@ -605,11 +611,11 @@ fn output_filename(&mut self, path: &Path) {
     fn framework_path(&mut self, _path: &Path) {
         bug!("frameworks are not supported on windows")
     }
-    fn link_framework(&mut self, _framework: &str) {
+    fn link_framework(&mut self, _framework: Symbol) {
         bug!("frameworks are not supported on windows")
     }
 
-    fn link_whole_staticlib(&mut self, lib: &str, _search_path: &[PathBuf]) {
+    fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) {
         // not supported?
         self.link_staticlib(lib);
     }
@@ -740,8 +746,8 @@ fn include_path(&mut self, path: &Path) {
         self.cmd.arg("-L").arg(path);
     }
 
-    fn link_staticlib(&mut self, lib: &str) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_staticlib(&mut self, lib: Symbol) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
     fn output_filename(&mut self, path: &Path) {
@@ -752,12 +758,12 @@ fn add_object(&mut self, path: &Path) {
         self.cmd.arg(path);
     }
 
-    fn link_dylib(&mut self, lib: &str) {
+    fn link_dylib(&mut self, lib: Symbol) {
         // Emscripten always links statically
         self.link_staticlib(lib);
     }
 
-    fn link_whole_staticlib(&mut self, lib: &str, _search_path: &[PathBuf]) {
+    fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) {
         // not supported?
         self.link_staticlib(lib);
     }
@@ -767,7 +773,7 @@ fn link_whole_rlib(&mut self, lib: &Path) {
         self.link_rlib(lib);
     }
 
-    fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
+    fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
         self.link_dylib(lib);
     }
 
@@ -803,7 +809,7 @@ fn framework_path(&mut self, _path: &Path) {
         bug!("frameworks are not supported on Emscripten")
     }
 
-    fn link_framework(&mut self, _framework: &str) {
+    fn link_framework(&mut self, _framework: Symbol) {
         bug!("frameworks are not supported on Emscripten")
     }
 
@@ -948,12 +954,12 @@ fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a>
 }
 
 impl<'a> Linker for WasmLd<'a> {
-    fn link_dylib(&mut self, lib: &str) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_dylib(&mut self, lib: Symbol) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
-    fn link_staticlib(&mut self, lib: &str) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_staticlib(&mut self, lib: Symbol) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
     fn link_rlib(&mut self, lib: &Path) {
@@ -995,16 +1001,16 @@ fn args(&mut self, args: &[String]) {
         self.cmd.args(args);
     }
 
-    fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
-    fn link_framework(&mut self, _framework: &str) {
+    fn link_framework(&mut self, _framework: Symbol) {
         panic!("frameworks not supported")
     }
 
-    fn link_whole_staticlib(&mut self, lib: &str, _search_path: &[PathBuf]) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
     fn link_whole_rlib(&mut self, lib: &Path) {
@@ -1087,18 +1093,41 @@ fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
         }
     }
 
-    let formats = tcx.sess.dependency_formats.borrow();
-    let deps = formats[&crate_type].iter();
+    let formats = tcx.dependency_formats(LOCAL_CRATE);
+    let deps = formats.iter().filter_map(|(t, list)| {
+        if *t == crate_type {
+            Some(list)
+        } else {
+            None
+        }
+    }).next().unwrap();
 
-    for (index, dep_format) in deps.enumerate() {
+    for (index, dep_format) in deps.iter().enumerate() {
         let cnum = CrateNum::new(index + 1);
         // For each dependency that we are linking to statically ...
         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());
             }
         }
     }
@@ -1162,19 +1191,19 @@ fn finalize(&mut self) -> Command {
         ::std::mem::replace(&mut self.cmd, Command::new(""))
     }
 
-    fn link_dylib(&mut self, _lib: &str) {
+    fn link_dylib(&mut self, _lib: Symbol) {
         panic!("external dylibs not supported")
     }
 
-    fn link_rust_dylib(&mut self, _lib: &str, _path: &Path) {
+    fn link_rust_dylib(&mut self, _lib: Symbol, _path: &Path) {
         panic!("external dylibs not supported")
     }
 
-    fn link_staticlib(&mut self, _lib: &str) {
+    fn link_staticlib(&mut self, _lib: Symbol) {
         panic!("staticlibs not supported")
     }
 
-    fn link_whole_staticlib(&mut self, _lib: &str, _search_path: &[PathBuf]) {
+    fn link_whole_staticlib(&mut self, _lib: Symbol, _search_path: &[PathBuf]) {
         panic!("staticlibs not supported")
     }
 
@@ -1182,7 +1211,7 @@ fn framework_path(&mut self, _path: &Path) {
         panic!("frameworks not supported")
     }
 
-    fn link_framework(&mut self, _framework: &str) {
+    fn link_framework(&mut self, _framework: Symbol) {
         panic!("frameworks not supported")
     }