L'implémentation de std::mem::drop
est documentée comme suit:
pub fn drop<T>(_x: T) { }
En tant que tel, je m'attendrais à ce que la fermeture |_| ()
(familièrement connue sous le nom de fermeture des toilettes ) soit un remplacement potentiel de 1: 1 drop
dans les deux sens. Cependant, le code ci-dessous montre que ce drop
n'est pas compatible avec un trait de rang supérieur lié au paramètre de la fonction, contrairement à la fermeture des toilettes.
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!
}
Message d'erreur du compilateur:
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
Étant donné que drop
c'est censé être générique par rapport à n'importe quelle taille T
, il semble déraisonnable que la signature "plus générique" fn(_) -> _
ne soit pas compatible avec for<'a> fn (&'a _) -> _
. Pourquoi le compilateur n'admet-il pas la signature d' drop
ici, et qu'est-ce qui le rend différent lorsque la fermeture des toilettes est placée à sa place?