diff options
| author | Stuart Cook <Zalathar@users.noreply.github.com> | 2025-07-31 15:42:00 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-31 15:42:00 +1000 |
| commit | 8628b78f24c01026d01b82afd3ec91a2019fe647 (patch) | |
| tree | 5275877553f3c35fcf1ea74dc9a0e1a14fcd223a /tests | |
| parent | f478bec907b6c7c945d9de4da488d55f6a90dd82 (diff) | |
| parent | a448837045326d7c33059dc3aa2d1d87529dcf3d (diff) | |
| download | rust-8628b78f24c01026d01b82afd3ec91a2019fe647.tar.gz rust-8628b78f24c01026d01b82afd3ec91a2019fe647.zip | |
Rollup merge of #144232 - xacrimon:explicit-tail-call, r=WaffleLapkin
Implement support for `become` and explicit tail call codegen for the LLVM backend This PR implements codegen of explicit tail calls via `become` in `rustc_codegen_ssa` and support within the LLVM backend. Completes a task on (https://github.com/rust-lang/rust/issues/112788). This PR implements all the necessary bits to make explicit tail calls usable, other backends have received stubs for now and will ICE if you use `become` on them. I suspect there is some bikeshedding to be done on how we should go about implementing this for other backends, but it should be relatively straightforward for GCC after this is merged. During development I also put together a POC bytecode VM based on tail call dispatch to test these changes out and analyze the codegen to make sure it generates expected assembly. That is available [here](https://github.com/xacrimon/tcvm).
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/codegen-llvm/become-musttail.rs | 18 | ||||
| -rw-r--r-- | tests/ui/explicit-tail-calls/recursion-etc.rs | 17 |
2 files changed, 35 insertions, 0 deletions
diff --git a/tests/codegen-llvm/become-musttail.rs b/tests/codegen-llvm/become-musttail.rs new file mode 100644 index 00000000000..07f33571910 --- /dev/null +++ b/tests/codegen-llvm/become-musttail.rs @@ -0,0 +1,18 @@ +//@ compile-flags: -C opt-level=0 -Cpanic=abort -C no-prepopulate-passes +//@ needs-unwind + +#![crate_type = "lib"] +#![feature(explicit_tail_calls)] + +// CHECK-LABEL: define {{.*}}@fibonacci( +#[no_mangle] +#[inline(never)] +pub fn fibonacci(n: u64, a: u64, b: u64) -> u64 { + // CHECK: musttail call {{.*}}@fibonacci( + // CHECK-NEXT: ret i64 + match n { + 0 => a, + 1 => b, + _ => become fibonacci(n - 1, b, a + b), + } +} diff --git a/tests/ui/explicit-tail-calls/recursion-etc.rs b/tests/ui/explicit-tail-calls/recursion-etc.rs new file mode 100644 index 00000000000..8c89ceb7869 --- /dev/null +++ b/tests/ui/explicit-tail-calls/recursion-etc.rs @@ -0,0 +1,17 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(explicit_tail_calls)] + +use std::hint::black_box; + +pub fn count(curr: u64, top: u64) -> u64 { + if black_box(curr) >= top { + curr + } else { + become count(curr + 1, top) + } +} + +fn main() { + println!("{}", count(0, black_box(1000000))); +} |
