The problem is an incompatibility, (which I’ll show how to resolve) between unique closure types, how generics are instantiated when Rust is compiled, and a recursive use of the closure.
fn map_nodes<F, R>(f: F, n: &Node) -> Vec<R>
where
F: Fn(&Node) -> R,
Each recursive call instantiates a new version of this function, with a new type inserted for F
. In this case, the map_nodes
receives F
and passes on &F
, and it creates an infinite series of new map_nodes
specializations that would need to be compiled.
What you can do instead is use a concrete closure type by using a reference to a Fn
trait object:
fn map_nodes<R>(f: &Fn(&Node) -> R, n: &Node) -> Vec<R>
This would require inserting a &
before the lambda expression where the closure is used: map_nodes(&|n| n.children.len(), &node)
.
If you don’t want to burden your public API with this difference, then you can use an internal wrapper for your recursive function instead:
fn map_nodes<F, R>(f: F, n: &Node) -> Vec<R>
where
F: Fn(&Node) -> R,
{
fn map_nodes_inner<R>(f: &Fn(&Node) -> R, n: &Node) -> Vec<R> {
let mut v: Vec<R> = Vec::new();
v.push(f(n));
v.extend(n.children.iter().flat_map(|child| map_nodes_inner(f, &child)));
v
}
map_nodes_inner(&f, n)
}