Skip to content

redundant_closure false positive with as_deref #13073

Closed
@martinetd

Description

@martinetd

Summary

redundant_closure closure suggests to remove a closure and causes a lifetime issue.

I'll admit I have no idea why using a closure is different here... This can be worked around by using a match switch instead, I couldn't even get an intermediate variable to work.

Lint Name

redundant_closure

Reproducer

This code:

fn get_default() -> Option<&'static str> {
    Some("foo")
}       

struct Stuff {
    field: Option<String>,
}

fn main() {
    let stuff = Stuff { field: None };
    let field = stuff.field.as_deref().or_else(|| get_default()).unwrap();
    //let field = stuff.field.as_deref().or_else(get_default).unwrap();

    println!("{:?}", field);
}   

Gives this warning:

warning: redundant closure
  --> src/main.rs:11:48
   |
11 |     let field = stuff.field.as_deref().or_else(|| get_default()).unwrap();
   |                                                ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
   = note: `#[warn(clippy::redundant_closure)]` on by default

warning: `r2` (bin "r2") generated 1 warning (run `cargo clippy --fix --bin "r2"` to apply 1 suggestion)

Applying the fix as is yields this error:

error[E0597]: `stuff.field` does not live long enough
  --> src/main.rs:12:17
   |
10 |     let stuff = Stuff { field: None };
   |         ----- binding `stuff` declared here
11 |     //let field = stuff.field.as_deref().or_else(|| get_default()).unwrap();
12 |     let field = stuff.field.as_deref().or_else(get_default).unwrap();
   |                 ^^^^^^^^^^^-----------
   |                 |
   |                 borrowed value does not live long enough
   |                 argument requires that `stuff.field` is borrowed for `'static`
...
15 | }
   | - `stuff.field` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.
error: could not compile `r2` (bin "r2") due to 1 previous error

Workaround:

    let field = match stuff.field.as_deref() {
        Some(x) => x,
        None => get_default().unwrap()
    };

Version

rustc 1.81.0-nightly (d8a38b000 2024-06-19)
binary: rustc
commit-hash: d8a38b00024cd7156dea4ce8fd8ae113a2745e7f
commit-date: 2024-06-19
host: x86_64-unknown-linux-gnu
release: 1.81.0-nightly
LLVM version: 18.1.7

Additional Labels

@rustbot label +I-false-positive +I-suggestion-causes-error

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't haveI-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