@@ -445,6 +445,35 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
445
445
if tcx.should_inherit_track_caller(did) {
446
446
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
447
447
}
448
+
449
+ // Foreign items by default use no mangling for their symbol name.
450
+ if tcx.is_foreign_item(did) {
451
+ // There's a few exceptions to this rule though:
452
+ if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
453
+ // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
454
+ // both for exports and imports through foreign items. This is handled further,
455
+ // during symbol mangling logic/
456
+ } else if codegen_fn_attrs.link_name.is_some() {
457
+ // * This can be overridden with the `#[link_name]` attribute
458
+ } else if tcx.sess.target.is_like_wasm
459
+ && tcx.wasm_import_module_map(LOCAL_CRATE).contains_key(&did.into())
460
+ {
461
+ // * On the wasm32 targets there is a bug (or feature) in LLD [1] where the
462
+ // same-named symbol when imported from different wasm modules will get
463
+ // hooked up incorrectly. As a result foreign symbols, on the wasm target,
464
+ // with a wasm import module, get mangled. Additionally our codegen will
465
+ // deduplicate symbols based purely on the symbol name, but for wasm this
466
+ // isn't quite right because the same-named symbol on wasm can come from
467
+ // different modules. For these reasons if `#[link(wasm_import_module)]`
468
+ // is present we mangle everything on wasm because the demangled form will
469
+ // show up in the `wasm-import-name` custom attribute in LLVM IR.
470
+ //
471
+ // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316
472
+ } else {
473
+ // if none of the exceptions apply; apply no_mangle
474
+ codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
475
+ }
476
+ }
448
477
}
449
478
450
479
fn check_result(
0 commit comments