@@ -445,6 +445,35 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
445445 if tcx. should_inherit_track_caller ( did) {
446446 codegen_fn_attrs. flags |= CodegenFnAttrFlags :: TRACK_CALLER ;
447447 }
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+ }
448477}
449478
450479fn check_result (
0 commit comments