@@ -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