rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.97k stars 12.68k forks source link

`fn std::mem::drop()` not accepted as argument of type `fn(&Arg)` #96057

Open panstromek opened 2 years ago

panstromek commented 2 years ago

I tried this code:

struct Arg(i8);

fn takes_cb(cb: fn(&Arg)) {}

fn takes_arg(a: &Arg) {}

fn main() {
    takes_cb(takes_arg); // this is ok
    takes_cb(|_|( )); // this is ok
    takes_cb(drop); // this is an error
}

I expected to see this happen: I expect the code to compile. It looks like this should work, because drop should be more or less equivalent to toilet closure, it just has generic argument, but without any bounds, so it seems like it should be accepted here.

Instead, this happened:

Code doesn't compile with:

error[E0308]: mismatched types
   --> crates/legacy-zebra/src/game.rs:315:14
    |
315 |     takes_cb(drop);
    |              ^^^^ one type is more general than the other
    |
    = note: expected fn pointer `for<'r> fn(&'r Arg)`
               found fn pointer `fn(&Arg)`

Meta

rustc --version --verbose:

rustc 1.60.0-nightly (75d9a0ae2 2022-02-16)
binary: rustc
commit-hash: 75d9a0ae210dcd078b3985e3550b59064e6603bc
commit-date: 2022-02-16
host: x86_64-unknown-linux-gnu
release: 1.60.0-nightly
LLVM version: 13.0.0
csmoe commented 2 years ago

Duplicate of https://github.com/rust-lang/rust/issues/41078#issuecomment-552062755

panstromek commented 2 years ago

@csmoe That doesn't seem like the same issue, because https://github.com/rust-lang/rust/issues/41078 talks about inferred types of closures, but here the problem is with a free function, not a closure. The problem doesn't seem to be an inference, but coercion.

csmoe commented 2 years ago

Your fn cb1(_s: &S) -> bool is also sugar, for fn cb1<'a>(_s: &'a S) -> bool, so you get that same for<'a> aspect ahead of the filter(cb1).

fn(_: &Arg) and Fn(&Arg) "share" the same higher rank trait bound as for<'a> fn(&'a Arg) cc https://rust-lang.github.io/rfcs/0387-higher-ranked-trait-bounds.html, so let alone the closure/function words in the comment.

panstromek commented 2 years ago

The problem here is that drop is generic, so it can't even express such a bound because the reference is just <T> in drop's definition. Is that really the same issue as incorrect type inference of a closure? I still don't see the connection.