rust-lang / rust-lang/rust

Worse optimization with `fn() -> !` than `fn()` or `fn() -> ()` with `-Crelocation-model=static`

Open
#153,976 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-codegen A-LLVM C-bug C-optimization T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code with the following flags: -O -Crelocation-model=static, with the target being i686-unknown-linux-gnu (similar things happened with other targets that I checked, including x86-unknown-linux-gnu)

#[unsafe(no_mangle)]
fn base(ptr: fn()) {
    ptr();
}

#[unsafe(no_mangle)]
fn worse(ptr: fn() -> !) {
    ptr();
}

I expected to see this happen: The assembly of those programs are equal, or worse() is better because more is known by the compiler

Instead, this happened:
The assembly for worse() used 16 more bytes of stack for no reason

base:
        jmp     dword ptr [esp + 4]

worse:
        sub     esp, 12
        call    dword ptr [esp + 16]

Note that the better code is also emitted if the fn ptr returns ().

rustc --version --verbose:

rustc 1.96.0-nightly (1d8897a4e 2026-03-13)
binary: rustc
commit-hash: 1d8897a4e88051480b36c501e66809425c6e08ad
commit-date: 2026-03-13
host: x86_64-unknown-linux-gnu
release: 1.96.0-nightly
LLVM version: 22.1.0

Also happens on 1.94

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the reported base and worse functions with -O -Crelocation-model=static for i686-unknown-linux-gnu, then compare their generated assembly. Investigate the compiler path handling function pointers returning !; done when worse() no longer uses unnecessary stack space and a regression test covers the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.