Description
When trying to reference a method on a generic type parameter from within a naked_asm!
block, rust-lld
reports a link-time error indicating that a symbol could not be resolved. This used to work on a Rust nightly from 2024-11-16, but no longer does on a recent nightly (2025-04-26), where naked_functions
has been stabilized (#134213).
Here's a link to a Rust playground that results in the link-time error:
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=9de6dd640b6e55f857e8d65bafb82ab1
A minimal example to trigger this bug:
trait T {
extern "C" fn t();
}
enum E<const C: usize> {}
impl<const C: usize> T for E<C> {
extern "C" fn t() {
println!("Const generic: {}", C);
}
}
#[unsafe(naked)]
extern "C" fn foo<U: T>() {
core::arch::naked_asm!(
"push rax",
"call {fn}",
"pop rax",
"ret",
fn = sym <U as T>::t,
);
}
fn main() {
foo::<E<42>>();
}
I expected to see this happen: correctly reference the proper, monomorphized function symbol <E<42> as T>::t
.
Instead, this happened:
error: linking with `cc` failed: exit status: 1
|
= note: "cc" "-m64" "/tmp/rustcQVxPkQ/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/tmp/rustcQVxPkQ/raw-dylibs" "-B<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld" "-fuse-ld=lld" "-Wl,-znostart-stop-gc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/playground/target/debug/build/aws-lc-sys-a7b8dbb98ccb03f8/out" "-L" "/playground/target/debug/build/libsqlite3-sys-f8b7023b84d9d43f/out" "-L" "/playground/target/debug/build/ring-75909fa7c1b7acce/out" "-L" "/playground/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/windows_x86_64_gnu-0.52.6/lib" "-L" "/playground/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/windows_aarch64_msvc-0.53.0/lib" "-L" "/playground/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/windows_i686_gnu-0.53.0/lib" "-L" "/playground/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/windows_i686_msvc-0.53.0/lib" "-L" "/playground/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/windows_x86_64_gnu-0.53.0/lib" "-L" "/playground/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/windows_x86_64_msvc-0.53.0/lib" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/playground/target/debug/deps/playground-72b3069f10cc7f34" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs"
= note: some arguments are omitted. use `--verbose` to show all linker arguments
= note: rust-lld: error: undefined hidden symbol: playground::T::t::h9639b9475488f044
>>> referenced by playground.5e532e3d8d2adfd6-cgu.0
>>> /playground/target/debug/deps/playground-72b3069f10cc7f34.playground.5e532e3d8d2adfd6-cgu.0.rcgu.o:(playground::foo::hebf1c66e7ecb3c3d)
collect2: error: ld returned 1 exit status
What's weird is that the symbol being referenced is not related to the actual type instantiation playground::E::<42>
, but only the trait-method playground::T::t
. Instead, on nightly-2024-11-16
, the generated assembly references the concrete type, as one would expect:
0000000000014e00 <_ZN29naked_asm_generic_symbol_test3foo17h05ccf99589ca4161E>:
; core::arch::naked_asm!(
14e00: 50 pushq %rax
14e01: e8 5a ff ff ff callq 0x14d60 <_ZN94_$LT$naked_asm_generic_symbol_test..E$LT$_$GT$$u20$as$u20$naked_asm_generic_symbol_test..T$GT$1t17h182ea722fc2c8c77E>
14e06: 58 popq %rax
14e07: c3 retq
14e08: 0f 0b ud2
Hopefully the above should be sufficient information to reproduce this bug. In the meantime, I can try to bisect which nightly channel update (and perhaps which EDIT: this error first started showing up on rustc
change) broke this.rustc 1.85.0-nightly (d4025ee45 2024-12-12)
, rustc 1.85.0-nightly (21fe748be 2024-12-11)
works correctly.
Meta
rustc --version --verbose
:
rustc 1.88.0-nightly (b4c8b0c3f 2025-04-25)
binary: rustc
commit-hash: b4c8b0c3f0533bb342a4873ff59bdad3883ab8e3
commit-date: 2025-04-25
host: x86_64-unknown-linux-gnu
release: 1.88.0-nightly
LLVM version: 20.1.2