about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-08-15 16:16:31 +1000
committerGitHub <noreply@github.com>2025-08-15 16:16:31 +1000
commit44eb7a167c9df395c803bf113a933f668b4c278a (patch)
tree0b352a5e4f981570afdb0135b40f873df7a56441 /tests
parent603b61df5768c95c994a4cde42898edf394c5f6f (diff)
parentfa18b3ebe29154440f6e8d9ad83021802b3aaa29 (diff)
downloadrust-44eb7a167c9df395c803bf113a933f668b4c278a.tar.gz
rust-44eb7a167c9df395c803bf113a933f668b4c278a.zip
Rollup merge of #144865 - WaffleLapkin:track-tail, r=lqd
Fix tail calls to `#[track_caller]` functions

We want `#[track_caller]` to be semver independent, i.e. it should not be a breaking change to add or remove it. Since it changes ABI of a function (adding an additional argument) we have to be careful to preserve this property when adding tail calls.

The only way to achieve this that I can see is:
- we forbid tail calls in functions which are marked with `#[track_caller]` (already implemented)
- tail-calling a `#[track_caller]` marked function downgrades the tail-call to a normal call (or equivalently tail-calls the shim made by fn def to fn ptr cast) (this pr)

Ideally the downgrade would be performed by a MIR pass, but that requires post mono MIR opts (cc ```@saethlin,``` rust-lang/rust#131650). For now I've changed code in cg_ssa to accomodate this behaviour (+ added a hack to mono collector so that the shim is actually generated)

Additionally I added a lint, although I don't think it's strictly necessary.

Alternative to rust-lang/rust#144762 (and thus closes rust-lang/rust#144762)
Fixes https://github.com/rust-lang/rust/issues/144755
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_track_caller.rs5
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_track_caller.stderr10
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_track_caller_polymorphic.rs20
-rw-r--r--tests/ui/explicit-tail-calls/callee_is_track_caller_polymorphic.stderr10
4 files changed, 43 insertions, 2 deletions
diff --git a/tests/ui/explicit-tail-calls/callee_is_track_caller.rs b/tests/ui/explicit-tail-calls/callee_is_track_caller.rs
index bcb93fda8c8..b85b335844b 100644
--- a/tests/ui/explicit-tail-calls/callee_is_track_caller.rs
+++ b/tests/ui/explicit-tail-calls/callee_is_track_caller.rs
@@ -1,10 +1,11 @@
-//@ check-pass
-// FIXME(explicit_tail_calls): make this run-pass, once tail calls are properly implemented
+//@ run-pass
+//@ ignore-pass
 #![expect(incomplete_features)]
 #![feature(explicit_tail_calls)]
 
 fn a(x: u32) -> u32 {
     become b(x);
+    //~^ warning: tail calling a function marked with `#[track_caller]` has no special effect
 }
 
 #[track_caller]
diff --git a/tests/ui/explicit-tail-calls/callee_is_track_caller.stderr b/tests/ui/explicit-tail-calls/callee_is_track_caller.stderr
new file mode 100644
index 00000000000..e1a251d156f
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/callee_is_track_caller.stderr
@@ -0,0 +1,10 @@
+warning: tail calling a function marked with `#[track_caller]` has no special effect
+  --> $DIR/callee_is_track_caller.rs:7:12
+   |
+LL |     become b(x);
+   |            ^^^^
+   |
+   = note: `#[warn(tail_call_track_caller)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/explicit-tail-calls/callee_is_track_caller_polymorphic.rs b/tests/ui/explicit-tail-calls/callee_is_track_caller_polymorphic.rs
new file mode 100644
index 00000000000..33384de83eb
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/callee_is_track_caller_polymorphic.rs
@@ -0,0 +1,20 @@
+//@ run-pass
+//@ ignore-pass
+#![expect(incomplete_features)]
+#![feature(explicit_tail_calls)]
+
+fn c<T: Trait>() {
+    become T::f();
+    //~^ warning: tail calling a function marked with `#[track_caller]` has no special effect
+}
+
+trait Trait {
+    #[track_caller]
+    fn f() {}
+}
+
+impl Trait for () {}
+
+fn main() {
+    c::<()>();
+}
diff --git a/tests/ui/explicit-tail-calls/callee_is_track_caller_polymorphic.stderr b/tests/ui/explicit-tail-calls/callee_is_track_caller_polymorphic.stderr
new file mode 100644
index 00000000000..5a1c40509ad
--- /dev/null
+++ b/tests/ui/explicit-tail-calls/callee_is_track_caller_polymorphic.stderr
@@ -0,0 +1,10 @@
+warning: tail calling a function marked with `#[track_caller]` has no special effect
+  --> $DIR/callee_is_track_caller_polymorphic.rs:7:12
+   |
+LL |     become T::f();
+   |            ^^^^^^
+   |
+   = note: `#[warn(tail_call_track_caller)]` on by default
+
+warning: 1 warning emitted
+