Skip to content

Commit 20d6246

Browse files
committed
the #[track_caller] shim should not inherit #[no_mangle]
1 parent 42d009c commit 20d6246

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ impl<'tcx> TyCtxt<'tcx> {
1313
self,
1414
instance_kind: InstanceKind<'_>,
1515
) -> Cow<'tcx, CodegenFnAttrs> {
16+
// NOTE: we try to not clone the `CodegenFnAttrs` when that is not needed.
17+
// The `to_mut` method used below clones the inner value.
1618
let mut attrs = Cow::Borrowed(self.codegen_fn_attrs(instance_kind.def_id()));
1719

1820
// Drop the `#[naked]` attribute on non-item `InstanceKind`s, like the shims that
@@ -23,6 +25,28 @@ impl<'tcx> TyCtxt<'tcx> {
2325
}
2426
}
2527

28+
// A shim created by `#[track_caller]` should not inherit any attributes
29+
// that modify the symbol name. Failing to remove these attributes from
30+
// the shim leads to errors like `symbol `foo` is already defined`.
31+
//
32+
// A `ClosureOnceShim` with the track_caller attribute does not have a symbol,
33+
// and therefore can be skipped here.
34+
if let InstanceKind::ReifyShim(_, _) = instance_kind
35+
&& attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
36+
{
37+
if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
38+
attrs.to_mut().flags.remove(CodegenFnAttrFlags::NO_MANGLE);
39+
}
40+
41+
if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
42+
attrs.to_mut().flags.remove(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
43+
}
44+
45+
if attrs.symbol_name.is_some() {
46+
attrs.to_mut().symbol_name = None;
47+
}
48+
}
49+
2650
attrs
2751
}
2852
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ run-pass
2+
#![feature(rustc_attrs)]
3+
4+
// The shim that is generated for a function annotated with `#[track_caller]` should not inherit
5+
// attributes that modify its symbol name. Failing to remove these attributes from the shim
6+
// leads to errors like `symbol `foo` is already defined`.
7+
//
8+
// See also https://github.com/rust-lang/rust/issues/143162.
9+
10+
#[unsafe(no_mangle)]
11+
#[track_caller]
12+
pub fn foo() {}
13+
14+
#[unsafe(export_name = "bar")]
15+
#[track_caller]
16+
pub fn bar() {}
17+
18+
#[rustc_std_internal_symbol]
19+
#[track_caller]
20+
pub fn baz() {}
21+
22+
fn main() {
23+
let _a = foo as fn();
24+
let _b = bar as fn();
25+
let _c = baz as fn();
26+
}

0 commit comments

Comments
 (0)