Change:
I tried this code: Build with With recent nighties it fails to link: This issue does not occur with or . searched nightlies: from nightly-2022-04-24 to nightly-2022-04-28 regressed nightly: nightly-2022-04-26 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.3</summaryHost triple: x8664-unknown-linux-gnu Reproduce with: </details
cc This may potentially be reproducible with too. UPD: It does reproduce on , even on hello-world, if LLD is used as a linker instead of UPD2: needs to have one additional "feature-enabling" symbol on these targets, see in LLD sources.
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-medium
Thanks for the quick fix!

Discussion:
// so add an empty section. if file.format() == object::BinaryFormat::Coff { file.add_section(Vec::new(), ".text".into(), object::SectionKind::Text); <ins> // We handle the name decoration of COFF targets in `symbol_export.rs`, so disable the // default mangler in `object` crate. file.set_mangling(object::write::Mangling::None); // Add feature flags to the object file. On MSVC this is optional but LLD will complain if // not present. let mut feature = 0; if file.architecture() == object::Architecture::I386 { // Indicate that all SEH handlers are registered in .sxdata section. // We don't have generate any code, so we don't need .sxdata section but LLD still // expects us to set this bit (see #96498). // Reference: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format feature |= 1; } file.add_symbol(object::write::Symbol { name: "@feat.00".into(), value: feature, size: 0, kind: object::SymbolKind::Data, scope: object::SymbolScope::Compilation, weak: false, section: object::write::SymbolSection::Absolute, flags: object::SymbolFlags::None, }); </ins> } for (sym, kind) in symbols.iter() {

for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| { if info.level.is_below_threshold(export_threshold) || info.used { symbols.push(( <del> symbol_export::symbol_name_for_instance_in_crate(tcx, symbol, cnum), </del> <ins> symbol_export::linking_symbol_name_for_instance_in_crate(tcx, symbol, cnum), </ins> info.kind, )); }

use rustc_middle::ty::query::{ExternProviders, Providers}; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::Instance; <del> use rustc_middle::ty::{SymbolName, TyCtxt}; </del> <ins> use rustc_middle::ty::{self, SymbolName, TyCtxt}; </ins> use rustc_session::config::CrateType; use rustc_target::spec::SanitizerSet;

} } <ins> /// This is the symbol name of the given instance as seen by the linker. /// /// On 32-bit Windows symbols are decorated according to their calling conventions. pub fn linking_symbol_name_for_instance_in_crate<'tcx>( tcx: TyCtxt<'tcx>, symbol: ExportedSymbol<'tcx>, instantiating_crate: CrateNum, ) -> String { use rustc_target::abi::call::Conv; let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate); let target = &tcx.sess.target; if !target.is_like_windows { // Mach-O has a global "_" suffix and `object` crate will handle it. // ELF does not have any symbol decorations. return undecorated; } let x86 = match &target.arch[..] { "x86" => true, "x86_64" => false, // Only x86/64 use symbol decorations. _ => return undecorated, }; let instance = match symbol { ExportedSymbol::NonGeneric(def_id) | ExportedSymbol::Generic(def_id, _) if tcx.is_static(def_id) => { None } ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)), ExportedSymbol::Generic(def_id, substs) => Some(Instance::new(def_id, substs)), // DropGlue always use the Rust calling convention and thus follow the target's default // symbol decoration scheme. ExportedSymbol::DropGlue(..) => None, // NoDefId always follow the target's default symbol decoration scheme. ExportedSymbol::NoDefId(..) => None, }; let (conv, args) = instance .map(|i| { tcx.fn_abi_of_instance(ty::ParamEnv::reveal_all().and((i, ty::List::empty()))) .unwrap_or_else(|_| bug!("fn_abi_of_instance({i:?}) failed")) }) .map(|fnabi| (fnabi.conv, &fnabi.args[..])) .unwrap_or((Conv::Rust, &[])); // Decorate symbols with prefices, suffices and total number of bytes of arguments. // Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170 let (prefix, suffix) = match conv { Conv::X86Fastcall => ("@", "@"), Conv::X86Stdcall => ("_", "@"), Conv::X86VectorCall => ("", "@@"), _ => { if x86 { undecorated.insert(0, '_'); } return undecorated; } }; let args_in_bytes: u64 = args .iter() .map(|abi| abi.layout.size.bytes().next_multiple_of(target.pointer_width as u64 / 8)) .sum(); format!("{prefix}{undecorated}{suffix}{args_in_bytes}") } </ins> fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, String> { // Build up a map from DefId to a `NativeLib` structure, where // `NativeLib` internally contains information about

#![feature(nll)] #![feature(associated_type_bounds)] #![feature(strict_provenance)] <ins> #![feature(int_roundings)] </ins> #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)]

<ins> # only-windows # needs-rust-lld -include ../../run-make-fulldeps/tools.mk # Ensure that LLD can link all: $(RUSTC) -C linker=rust-lld foo.rs </ins>

<ins> #![crate_type = "cdylib"] #[no_mangle] extern "C" fn foo() {} </ins>

<ins> // build-pass // only-x86-windows #![crate_type = "cdylib"] #![feature(abi_vectorcall)] #[no_mangle] extern "stdcall" fn foo(_: bool) {} #[no_mangle] extern "fastcall" fn bar(_: u8) {} #[no_mangle] extern "vectorcall" fn baz(_: u16) {} </ins>