Skip to content

Failed assert got 1400 instead of 14 after become tail call at -O3 #158017

@kevin-valerio

Description

@kevin-valerio

-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

Metadata

Metadata

Assignees

Labels

A-codegenArea: Code generationC-bugCategory: This is a bug.F-explicit_tail_calls`#![feature(explicit_tail_calls)]`F-unboxed_closures`#![feature(unboxed_closures)]`I-miscompileIssue: Correct Rust code lowers to incorrect machine codeT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions