Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False positive for redundant_closure lint #1439

Closed
samestep opened this issue Jan 13, 2017 · 5 comments · Fixed by #4032
Closed

False positive for redundant_closure lint #1439

samestep opened this issue Jan 13, 2017 · 5 comments · Fixed by #4032
Labels
C-bug Category: Clippy is not doing the correct thing E-medium Call for participation: Medium difficulty level problem and requires some initial experience.

Comments

@samestep
Copy link

I wrote a simple thunk implementation:

struct Thunk<T>(Box<FnMut() -> T>);

impl<T> Thunk<T> {
    fn new<F: 'static + FnOnce() -> T>(f: F) -> Thunk<T> {
        let mut option = Some(f);
        Thunk(Box::new(move || option.take().unwrap()()))
    }

    fn unwrap(self) -> T {
        let Thunk(mut f) = self;
        f()
    }
}

fn main() {
    let thunk = Thunk::new(|| println!("Hello, world!"));
    thunk.unwrap()
}

However, clippy complains that the closure in Thunk::new is redundant:

warning: redundant closure found, #[warn(redundant_closure)] on by default
 --> src/main.rs:6:24
  |
6 |         Thunk(Box::new(move || option.take().unwrap()()))
  |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
help: remove closure as shown:
  |         Thunk(Box::new(option.take().unwrap()))
  = help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#redundant_closure

But if I use clippy's suggestion, I get this error:

error[E0277]: the trait bound `F: std::ops::FnMut<()>` is not satisfied
 --> src/main.rs:6:15
  |
6 |         Thunk(Box::new(option.take().unwrap()))
  |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::FnMut<()>` is not implemented for `F`
  |
  = help: consider adding a `where F: std::ops::FnMut<()>` bound
  = note: required for the cast to the object type `std::ops::FnMut() -> T + 'static`

This seems like a bug in the redundant_closure lint.

@oli-obk
Copy link
Contributor

oli-obk commented Jan 13, 2017

Ugh... Box<FnOnce> ... We should just bail when encountering it...

@oli-obk oli-obk added E-medium Call for participation: Medium difficulty level problem and requires some initial experience. C-bug Category: Clippy is not doing the correct thing labels Jan 13, 2017
@mtak-
Copy link

mtak- commented Mar 30, 2018

This is also triggering on my code which does not have a box, but is similarly lazy. Here is a minimal repro for v0.0.191.

struct Wrapper<T>(Option<T>);

impl<T> Wrapper<T> {
    fn map_it<U, V>(&mut self, other: Wrapper<U>) -> Wrapper<V>
    where
        T: FnOnce(U) -> V,
    {
        Wrapper(other.0.map(|u| self.0.take().expect("")(u)))
    }
}
warning: redundant closure found
  --> src/private/map.rs:44:29
   |
44 |         Wrapper(other.0.map(|u| self.0.take().expect("")(u)))
   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove closure as shown: `self.0.take().expect("")`
   |
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.191/index.html#redundant_closure

EDIT: Too minimal, i think clippy is correct here.

@phansch
Copy link
Member

phansch commented Apr 29, 2018

Going to take a look at this over the next couple of days

@Nemo157
Copy link
Member

Nemo157 commented Jul 21, 2018

Here is a pretty minimal repro:

#[allow(unknown_lints, blacklisted_name)]
fn main() {
    let mut foo = Some(|x| x * x);
    let bar = [Ok(1), Err(2)];
    let baz: Vec<_> = bar.iter().map(|x| x.map_err(|e| foo.take().unwrap()(e))).collect();
    // let baz: Vec<_> = bar.iter().map(|x| x.map_err(foo.take().unwrap())).collect();
    println!("{:?}", baz);
}

Nemo157 added a commit to Nemo157/rust-clippy that referenced this issue Jul 21, 2018
@phansch
Copy link
Member

phansch commented Jul 25, 2018

I didn't have enough time to dig into this, unfortunately. If someone wants to pick this up, feel free!

phansch added a commit to phansch/rust-clippy that referenced this issue Apr 25, 2019
These two cases were fixed by rust-lang#4008.

Closes rust-lang#1439

changelog: none
phansch added a commit to phansch/rust-clippy that referenced this issue Apr 26, 2019
These two cases were fixed by rust-lang#4008.

Closes rust-lang#1439

changelog: none
bors added a commit that referenced this issue Apr 29, 2019
Add two more tests for redundant_closure

These two cases were fixed by #4008.

Closes #1439

changelog: none
bors added a commit that referenced this issue Apr 29, 2019
Add two more tests for redundant_closure

These two cases were fixed by #4008.

Closes #1439

changelog: none
bors added a commit that referenced this issue Apr 29, 2019
Add two more tests for redundant_closure

These two cases were fixed by #4008.

Closes #1439

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing E-medium Call for participation: Medium difficulty level problem and requires some initial experience.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants