]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_codegen_utils/symbol_names.rs
Auto merge of #67303 - dtolnay:rls, r=Xanewok
[rust.git] / src / librustc_codegen_utils / symbol_names.rs
index 7ccd024769f757179a4af9e1b4cf5e8d2c14067f..bd714f5c6b715b354effd7335faebd6ca228819b 100644 (file)
 //! DefPaths which are much more robust in the face of changes to the code base.
 
 use rustc::hir::def_id::LOCAL_CRATE;
-use rustc::hir::Node;
 use rustc::hir::CodegenFnAttrFlags;
+use rustc::hir::Node;
+use rustc::mir::mono::{InstantiationMode, MonoItem};
 use rustc::session::config::SymbolManglingVersion;
 use rustc::ty::query::Providers;
-use rustc::ty::{self, TyCtxt, Instance};
-use rustc::mir::mono::{MonoItem, InstantiationMode};
+use rustc::ty::{self, Instance, TyCtxt};
 
-use syntax_pos::symbol::InternedString;
+use syntax_pos::symbol::Symbol;
 
 use log::debug;
 
 
 pub fn provide(providers: &mut Providers<'_>) {
     *providers = Providers {
-        symbol_name: |tcx, instance| ty::SymbolName {
-            name: symbol_name(tcx, instance),
-        },
+        symbol_name: |tcx, instance| ty::SymbolName { name: symbol_name(tcx, instance) },
 
         ..*providers
     };
 }
 
-fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString {
+fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol {
     let def_id = instance.def_id();
     let substs = instance.substs;
 
@@ -123,13 +121,11 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString {
     if def_id.is_local() {
         if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) {
             let disambiguator = tcx.sess.local_crate_disambiguator();
-            return
-                InternedString::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator));
+            return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator));
         }
         if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) {
             let disambiguator = tcx.sess.local_crate_disambiguator();
-            return
-                InternedString::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator));
+            return Symbol::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator));
         }
     }
 
@@ -144,25 +140,44 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString {
     };
 
     let attrs = tcx.codegen_fn_attrs(def_id);
+
+    // Foreign items by default use no mangling for their symbol name. There's a
+    // few exceptions to this rule though:
+    //
+    // * This can be overridden with the `#[link_name]` attribute
+    //
+    // * On the wasm32 targets there is a bug (or feature) in LLD [1] where the
+    //   same-named symbol when imported from different wasm modules will get
+    //   hooked up incorectly. As a result foreign symbols, on the wasm target,
+    //   with a wasm import module, get mangled. Additionally our codegen will
+    //   deduplicate symbols based purely on the symbol name, but for wasm this
+    //   isn't quite right because the same-named symbol on wasm can come from
+    //   different modules. For these reasons if `#[link(wasm_import_module)]`
+    //   is present we mangle everything on wasm because the demangled form will
+    //   show up in the `wasm-import-name` custom attribute in LLVM IR.
+    //
+    // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316
     if is_foreign {
-        if let Some(name) = attrs.link_name {
-            return name.as_interned_str();
+        if tcx.sess.target.target.arch != "wasm32"
+            || !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id)
+        {
+            if let Some(name) = attrs.link_name {
+                return name;
+            }
+            return tcx.item_name(def_id);
         }
-        // Don't mangle foreign items.
-        return tcx.item_name(def_id).as_interned_str();
     }
 
-    if let Some(name) = &attrs.export_name {
+    if let Some(name) = attrs.export_name {
         // Use provided name
-        return name.as_interned_str();
+        return name;
     }
 
     if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
         // Don't mangle
-        return tcx.item_name(def_id).as_interned_str();
+        return tcx.item_name(def_id);
     }
 
-
     let is_generic = substs.non_erasable_generics().next().is_some();
     let avoid_cross_crate_conflicts =
         // If this is an instance of a generic function, we also hash in
@@ -222,5 +237,5 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString {
         SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate),
     };
 
-    InternedString::intern(&mangled)
+    Symbol::intern(&mangled)
 }