La implementación de std::mem::drop
está documentada para ser la siguiente:
pub fn drop<T>(_x: T) { }
Como tal, esperaría que el cierre |_| ()
(conocido coloquialmente como cierre del inodoro ) sea un posible reemplazo 1: 1 drop
, en ambas direcciones. Sin embargo, el siguiente código muestra que drop
no es compatible con un rasgo de mayor rango vinculado al parámetro de la función, mientras que el cierre del inodoro sí.
fn foo<F, T>(f: F, x: T)
where
for<'a> F: FnOnce(&'a T),
{
dbg!(f(&x));
}
fn main() {
foo(|_| (), "toilet closure"); // this compiles
foo(drop, "drop"); // this does not!
}
El mensaje de error del compilador:
error[E0631]: type mismatch in function arguments
--> src/main.rs:10:5
|
1 | fn foo<F, T>(f: F, x: T)
| ---
2 | where
3 | for<'a> F: FnOnce(&'a T),
| ------------- required by this bound in `foo`
...
10 | foo(drop, "drop"); // this does not!
| ^^^
| |
| expected signature of `for<'a> fn(&'a _) -> _`
| found signature of `fn(_) -> _`
error[E0271]: type mismatch resolving `for<'a> <fn(_) {std::mem::drop::<_>} as std::ops::FnOnce<(&'a _,)>>::Output == ()`
--> src/main.rs:10:5
|
1 | fn foo<F, T>(f: F, x: T)
| ---
2 | where
3 | for<'a> F: FnOnce(&'a T),
| ------------- required by this bound in `foo`
...
10 | foo(drop, "drop"); // this does not!
| ^^^ expected bound lifetime parameter 'a, found concrete lifetime
Teniendo en cuenta que drop
es supuestamente genérico con respecto a cualquier tamaño T
, no parece razonable que la firma "más genérica" fn(_) -> _
no sea compatible for<'a> fn (&'a _) -> _
. ¿Por qué el compilador no admite la firma de drop
aquí, y qué lo hace diferente cuando el cierre del inodoro se coloca en su lugar?