Closures now typecheck against `fn`?

I'm reading Programming Rust (Blandy & Orendorff 2017) and I'm a bit confused by their discussion of closure types. In particular, they say that "closures do not have the same type as functions", and that in order to pass either as an argument to another function, generics must be used with trait bounds on Fn / FnMut / FnOnce.

And indeed, I seem to remember that code like this didn't use to compile...

fn arg_fn(i: i32) -> i32 {
    i
}

fn takes_fn(f: fn(i32) -> i32) {
    f(1);
}

fn main() {
    takes_fn(arg_fn);
    takes_fn(|x| x);
}

... but now it definitely does. Did this change at some point? I tried searching the edition guide but couldn't come up with anything relevant. Or maybe I'm just misinterpreting the information in the book?

There's an exception that closures that do not capture any variables are just ordinary functions. That was probably a small enough change some time during the past year, so it isn't part of the edition guide.

Closures that do capture something would still not work here.

3 Likes

What @vorner is referring to was done here.

3 Likes

Oh, right! Makes sense :slight_smile: Thanks for the explanation and link!

1 Like