Skip to content

-> impl Fn() fails with closures used as FnMut but actually Fn #59022

@mtak-

Description

@mtak-

It's clear that the closure could implement Fn, but for some reason this code does not compile.

fn constrain<F: FnMut()>(f: F) -> F {
    f
}

pub fn foo() -> impl Fn() { // works if FnMut
    constrain(|| {})
}

Error

error[E0277]: expected a `std::ops::Fn<()>` closure, found `[closure@src/lib.rs:6:15: 6:20]`
 --> src/lib.rs:5:17
  |
5 | pub fn foo() -> impl Fn() { // works if FnMut
  |                 ^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@src/lib.rs:6:15: 6:20]`
  |
  = help: the trait `std::ops::Fn<()>` is not implemented for `[closure@src/lib.rs:6:15: 6:20]`
  = note: wrap the `[closure@src/lib.rs:6:15: 6:20]` in a closure with no arguments: `|| { /* code */ }
  = note: the return type of a function must have a statically known size

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=a97dd1def3526265d57cfa1f8236e38a

This bit someone at our company who's relatively new to rust while trying to return a std::iter::Map<.., impl Fn(..)->..>. The Iterator::map function appears to have the same effect as constrain.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions