-O3 passes the previous stack values instead of the tuple values passed to the tail call
I tried a patch but it's a non trivial one so I haven't submitted any PR
Repro:
#![feature(explicit_tail_calls, unboxed_closures)]
#![expect(incomplete_features)]
#![allow(dead_code)]
#[derive(Copy, Clone)]
struct Thing { a: u64, b: u64, c: u64, d: u64 }
#[inline(never)]
fn seed_stack() {
let mut values = (
Thing { a: 100, b: 200, c: 300, d: 400 },
Thing { a: 500, b: 600, c: 700, d: 800 },
);
std::hint::black_box(&mut values);
}
#[inline(never)]
extern "rust-call" fn callee((left, right): (Thing, Thing)) -> u64 {
left.a.wrapping_add(left.b).wrapping_add(right.a).wrapping_add(right.b)
}
#[inline(never)]
extern "rust-call" fn caller((left, right): (Thing, Thing)) -> u64 {
become callee((right, left));
}
fn main() {
seed_stack();
let left = Thing { a: 1, b: 2, c: 3, d: 4 };
let right = Thing { a: 5, b: 6, c: 7, d: 8 };
println!("got={}", caller((left, right)));
}
$ rustc +nightly-2026-05-10 repro.rs -C opt-level=0 -o repro_o0
$ ./repro_o0
got=14
$ rustc +nightly-2026-05-10 repro.rs -C opt-level=3 -o repro_o3
$ ./repro_o3
got=1400
-O3passes the previous stack values instead of the tuple values passed to the tail callI tried a patch but it's a non trivial one so I haven't submitted any PR
Repro: