Skip to content

clippy::redundant_closure: false positive when function returns ! but closure doesn't #8416

Closed
@Allen-Webb

Description

@Allen-Webb

Summary

For tests I have a mock for std::process::exit() that needs to return, so when std::process::exit() is passed in as the callback I wrap it in a closure to change the return type from ! to ().

Lint Name

clippy::redundant_closure

Reproducer

I tried this code:

fn do_thing_with_exit<F: FnMut(i32)>(mut exit_provider: F) {
    //Do thing
    exit_provider(0);
}

fn main() {
    // Example test code:
    let mut ret_code = -1i32;
    do_thing_with_exit(|v| { ret_code = v; });
    assert_eq!(ret_code, 0);

    // Example non-test code:
    do_thing_with_exit(|v| std::process::exit(v));
}

I saw this happen:

warning: redundant closure
  [--> src/main.rs:13:24
](https://play.rust-lang.org/#)   |
13 |     do_thing_with_exit(|v| std::process::exit(v));
   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `std::process::exit`
   |
   = note: `#[warn(clippy::redundant_closure)]` on by default
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure

I applied the suggestion:

fn do_thing_with_exit<F: FnMut(i32)>(mut exit_provider: F) {
    //Do thing
    exit_provider(0);
}

fn main() {
    // Example test code:
    let mut ret_code = -1i32;
    do_thing_with_exit(|v| { ret_code = v; });
    assert_eq!(ret_code, 0);

    // Example non-test code:
    do_thing_with_exit(std::process::exit);
}

This fails to compile with the error:

error[[E0271]](https://doc.rust-lang.org/stable/error-index.html#E0271): type mismatch resolving `<fn(i32) -> ! {exit} as FnOnce<(i32,)>>::Output == ()`
  [--> src/main.rs:13:5
](https://play.rust-lang.org/#)   |
13 |     do_thing_with_exit(std::process::exit);
   |     ^^^^^^^^^^^^^^^^^^ expected `()`, found `!`
   |
   = note: expected unit type `()`
                   found type `!`
note: required by a bound in `do_thing_with_exit`
  [--> src/main.rs:1:26
](https://play.rust-lang.org/#)   |
1  | fn do_thing_with_exit<F: FnMut(i32)>(mut exit_provider: F) {
   |                          ^^^^^^^^^^ required by this bound in `do_thing_with_exit`

For more information about this error, try `rustc --explain E0271`.

Version

I used 1.58.1 stable from play.rust-lang.org.

The clippy version is 0.1.60 (2022-02-10 e646f3d)

Additional Labels

No response

Metadata

Metadata

Assignees

Labels

C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions