Skip to content

Option->Result->Option used in ?-on-Option isn't a no-op #49437

Closed
@scottmcm

Description

@scottmcm

(Very similar to the rebuild-the-same-Result in #38349, but a bit more complex.)

pub fn foo(x: Option<i32>) -> Result<i32, std::option::NoneError> {
    match x {
        Some(v) => Ok(v),
        None => Err(std::option::NoneError),
    }
}

pub fn bar(x: Option<i32>) -> Option<i32> {
    match foo(x) {
        Ok(v) => Some(v),
        Err(_) => None,
    }
}

Ideally foo would just ^= 1 the discriminant, and bar would be a nop, but today

; playground::foo
; Function Attrs: norecurse nounwind readnone uwtable
define i64 @_ZN10playground3foo17hd0a7b7996c801050E(i64) unnamed_addr #0 {
start:
  %abi_cast.sroa.4.0.extract.shift = and i64 %0, -4294967296
  %1 = and i64 %0, 4294967295
  %switch = icmp eq i64 %1, 0
  %. = zext i1 %switch to i64
  %_0.sroa.0.0.insert.insert = or i64 %abi_cast.sroa.4.0.extract.shift, %.
  ret i64 %_0.sroa.0.0.insert.insert
}

; playground::bar
; Function Attrs: norecurse nounwind readnone uwtable
define i64 @_ZN10playground3bar17h7d7c40401a529d3eE(i64) unnamed_addr #0 {
start:
  %1 = and i64 %0, 4294967295
  %switch.i = icmp ne i64 %1, 0
  %abi_cast1.sroa.4.0.extract.shift = and i64 %0, -4294967296
  %. = zext i1 %switch.i to i64
  %_0.sroa.0.0.insert.insert = or i64 %abi_cast1.sroa.4.0.extract.shift, %.
  ret i64 %_0.sroa.0.0.insert.insert
}

https://play.rust-lang.org/?gist=dc3fab4d8a20e31552769a9a03504c4c&version=nightly&mode=release

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationC-enhancementCategory: An issue proposing an enhancement or a PR with one.I-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions