What does “Overflow evaluating the requirement” mean and how can I fix it?

后端 未结 2 387
天涯浪人
天涯浪人 2020-12-11 17:31

I\'m running into what is potentially a compiler bug. However, I don\'t understand the issue well enough to port the proposed solution to my own code. Here\'s a stripped-dow

2条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-11 17:58

    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: F, n: &Node) -> Vec
    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(f: &Fn(&Node) -> R, n: &Node) -> Vec
    

    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: F, n: &Node) -> Vec
    where
        F: Fn(&Node) -> R,
    {
        fn map_nodes_inner(f: &Fn(&Node) -> R, n: &Node) -> Vec {
            let mut v: Vec = 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)
    }
    

提交回复
热议问题