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=5c67759f67703a73f02671a5e1789b1b

// 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-bugCategory: This is a bug.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-slowIssue: Problems and improvements with respect to performance of generated code.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions