the `#[track_caller]` shim should not inherit `#[no_mangle]` fixes https://github.com/rust-lang/rust/issues/143162 builds on https://github.com/rust-lang/rust/pull/143293 which introduced a mechanism to strip attributes from shims. cc `@Jules-Bertholet` `@workingjubilee` `@bjorn3` --- Summary: This PR fixes an interaction between `#[track_caller]`, `#[no_mangle]`, and casting to a function pointer. A function annotated with `#[track_caller]` internally has a hidden extra argument for the panic location. The `#[track_caller]` attribute is only allowed on `extern "Rust"` functions. When a function is annotated with both `#[no_mangle]` and `#[track_caller]`, the exported symbol has the signature that includes the extra panic location argument. This works on stable rust today: ```rust extern "Rust" { #[track_caller] fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static>; } mod provides { use std::panic::Location; #[track_caller] // UB if we did not have this! #[no_mangle] fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static> { Location::caller() } } ``` When a `#[track_caller]` function is converted to a function pointer, a shim is added to drop the additional argument. So this is a valid program: ```rust #[track_caller] fn foo() {} fn main() { let f = foo as fn(); f(); } ``` The issue arises when `foo` is additionally annotated with `#[no_mangle]`, the generated shim currently inherits this attribute, also exporting a symbol named `foo`, but one without the hidden panic location argument. The linker rightfully complains about a duplicate symbol. The solution of this PR is to have the generated shim drop the `#[no_mangle]` attribute. |
||
|---|---|---|
| .. | ||
| back | ||
| debuginfo | ||
| mir | ||
| traits | ||
| assert_module_sources.rs | ||
| base.rs | ||
| codegen_attrs.rs | ||
| common.rs | ||
| errors.rs | ||
| lib.rs | ||
| meth.rs | ||
| mono_item.rs | ||
| size_of_val.rs | ||
| target_features.rs | ||