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