Skip to content

if-then-some-else-none changes return type #15257

Open
@matthiaskrgr

Description

@matthiaskrgr

Using the following flags

--force-warn clippy::if-then-some-else-none

this code:

fn main() {
    #[derive(Default)]
    pub struct Foo {}
    pub trait Bar {}
    impl Bar for Foo {}

    fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
        if i % 2 == 0 {
            Some(Box::new(Foo::default()))
        } else {
            None
        }
    }

    assert!(maybe_get_bar(2).is_some());
}

caused the following diagnostics:

    Checking _a v0.1.0 (/tmp/icemaker_global_tempdir.1bF2piwcjwmu/icemaker_clippyfix_tempdir.Rr5hVboHXTVo/_a)
warning: this could be simplified with `bool::then`
  --> src/main.rs:8:9
   |
8  | /         if i % 2 == 0 {
9  | |             Some(Box::new(Foo::default()))
10 | |         } else {
11 | |             None
12 | |         }
   | |_________^ help: try: `(i % 2 == 0).then(|| Box::new(Foo::default()))`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none
   = note: requested on the command line with `--force-warn clippy::if-then-some-else-none`

warning: `_a` (bin "_a") generated 1 warning (run `cargo clippy --fix --bin "_a"` to apply 1 suggestion)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.39s

However after applying these diagnostics, the resulting code:

fn main() {
    #[derive(Default)]
    pub struct Foo {}
    pub trait Bar {}
    impl Bar for Foo {}

    fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
        (i % 2 == 0).then(|| Box::new(Foo::default()))
    }

    assert!(maybe_get_bar(2).is_some());
}

no longer compiled:

    Checking _a v0.1.0 (/tmp/icemaker_global_tempdir.1bF2piwcjwmu/icemaker_clippyfix_tempdir.Rr5hVboHXTVo/_a)
error[E0308]: mismatched types
 --> src/main.rs:8:9
  |
7 |     fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
  |                                 -------------------- expected `std::option::Option<std::boxed::Box<(dyn main::Bar + 'static)>>` because of return type
8 |         (i % 2 == 0).then(|| Box::new(Foo::default()))
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<Box<dyn Bar>>`, found `Option<Box<Foo>>`
  |
  = note: expected enum `std::option::Option<std::boxed::Box<(dyn main::Bar + 'static)>>`
             found enum `std::option::Option<std::boxed::Box<main::Foo>>`
  = help: `main::Foo` implements `Bar` so you could box the found value and coerce it to the trait object `Box<dyn Bar>`, you will have to change the expected type as well

For more information about this error, try `rustc --explain E0308`.
error: could not compile `_a` (bin "_a") due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: could not compile `_a` (bin "_a" test) due to 1 previous error

Version:

rustc 1.90.0-nightly (9535feebd 2025-07-12)
binary: rustc
commit-hash: 9535feebd5741a55fc24e84060e82d41a75dac6e
commit-date: 2025-07-12
host: x86_64-unknown-linux-gnu
release: 1.90.0-nightly
LLVM version: 20.1.7

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-suggestion-causes-errorIssue: The suggestions provided by this Lint cause an ICE/error when applied

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions