Skip to content

Bad codegen with inlined functions returning Result with a niche. #148461

@ruriww

Description

@ruriww

I tried this code:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d140dcf5c739ec0a9511bf32bbb5def0

Edit (without black box):
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6c73f12739d118243ce152e1da6ef8d6

// change the error type to u16, u32, etc
// and how the vec's ptr field is stored is changed
type Result<T> = std::result::Result<T, u8>;

fn next_vec() -> Result<Vec<u8>> {
    if black_box(true) {
        let slice = black_box(&[1u8, 2, 3, 4]);

        Ok(slice.to_vec())
    } else {
        Err(5)
    }
}

fn add_vec(output: &mut Vec<u8>) -> Result<()> {
    // store here writes the `ptr` field of vec
    // split off by the error type `u8`,
    // as if Vec is still niched after moving it from
    // Ok(...)
    *output = next_vec()?;

    Ok(())
}

I expected to see this happen:

The ptr field of the vec is stored with a single instruction.

Instead, this happened (extended info available in the playground's run output):

The code for writing out a Vec<u8>:

  store i64 4, ptr %0, align 8
  store i8 %14, ptr %18, align 8
  %23 = getelementptr inbounds nuw i8, ptr %0, i64 9
  store i56 %16, ptr %23, align 1
  %24 = getelementptr inbounds nuw i8, ptr %0, i64 16
  store i64 4, ptr %24, align 1
  br label %25
    movb    %r15b, 8(%rbx)
    movl    %r14d, 9(%rbx)
    movq    %r14, %rax
    shrq    $48, %rax
    movb    %al, 15(%rbx)
    shrq    $32, %r14
    movw    %r14w, 13(%rbx)
    movq    $4, 16(%rbx)

Meta

Works on both stable 1.91 and nightly 1.93 2025-Nov on the playground, with lto = true or "thin".

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationC-bugCategory: This is a bug.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchneeds-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions