In rust-clippy, we have the following function:
fn over<X, F>(left: &[X], right: &[X], mut eq_fn: F) -> bool
where F: FnMut(&X, &X) -> bool {
left.len() == right.len() && left.iter().zip(right).all(|(x, y)|
eq_fn(x, y))
}
As it happens, rustc
's AST representation uses a lot of syntax::ptr::P<T>
pointers. Those dereference to T, and so autoderef implicitly coerces them to &T
if we use a closure. If we try to use a plain fn
however, we get a type mismatch:
error: type mismatch: the type `fn(&syntax::ast::Expr, &syntax::ast::Expr) -> bool {eq_op::is_exp_equal}` implements the trait `for<'r, 'r> core::ops::FnMut<(&'r syntax::ast::Expr, &'r syntax::ast::Expr)>`, but the trait `for<'r, 'r> core::ops::FnMut<(&'r syntax::ptr::P<syntax::ast::Expr>, &'r syntax::ptr::P<syntax::ast::Expr>)>` is required (expected struct `syntax::ptr::P`, found struct `syntax::ast::Expr`) [E0281]
Can I change the above function to accept both &[&T]
and &[P<T>]
and automatically coerce P<Expr>
into &Expr
? If so, how?
Both &T
and P<T>
implement Deref<Target = T>
, so you could use that in your bounds:
use std::ops::Deref;
fn over<X, F, X1, X2>(left: &[X1], right: &[X2], mut eq_fn: F) -> bool
where X1: Deref<Target = X>,
X2: Deref<Target = X>,
F: FnMut(&X, &X) -> bool {
left.len() == right.len() && left.iter().zip(right).all(|(x, y)|
eq_fn(x, y))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With