How to write generic function over pointer type?

In rust-clippy we have a 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 AST uses a lot of syntax::ptr::P<T> pointers. Those act out T, and so autoderef implicitly forces them to &T if we use closure. However, if we try to use a simple fn , 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 force P<Expr> to &Expr ? If so, how?

+5
source share
1 answer

Both &T and P<T> implement Deref<Target = T> , so you can use this within your own limits:

 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)) } 
+9
source

All Articles