//! virtually impossible. Thus, symbol hash generation exclusively relies on
//! 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::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+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 rustc_hir::def_id::LOCAL_CRATE;
+use rustc_hir::Node;
-use syntax_pos::symbol::Symbol;
+use rustc_span::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
};
};
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;
+ 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);
}
if let Some(name) = attrs.export_name {