I have the following code. Could you explain me why I get a lifetime error during building?
Note: here context
is ()
, but it is crucial to get this error. In real-world application I have something more sensible than unit type.
struct Tree {
parents: Vec<usize>,
}
#[derive(Clone)]
struct Node<'tree> {
tree: &'tree Tree,
idx: usize,
}
struct FindAtPathToRoot<'tree, F>
where
F: for<'a> Fn(&'a Node<'tree>) -> bool,
{
node: Option<Node<'tree>>,
func: F,
}
impl<'tree, F> Iterator for FindAtPathToRoot<'tree, F>
where
F: for<'a> Fn(&'a Node<'tree>) -> bool,
{
type Item = Node<'tree>;
fn next(&mut self) -> Option<Node<'tree>> {
loop {
let curr_node = self.node.take()?;
let next_idx = curr_node.tree.parents[curr_node.idx];
let next_node = if next_idx == curr_node.idx {
None
} else {
Some(Node {
tree: curr_node.tree,
idx: next_idx,
})
};
self.node = next_node;
if (self.func)(&curr_node) {
return Some(curr_node);
}
}
}
}
fn find_by_key<'a, 't: 'a, K, C, F>(
node: Node<'t>,
key: &'a K,
key_func: F,
context: &'a C,
) -> impl Iterator<Item = Node<'t>> + 'a
where
F: for<'c> Fn(&'c Node<'t>, &'a C) -> K + 'a,
K: Eq,
{
FindAtPathToRoot {
node: Some(node.clone()),
func: move |n: &Node| key_func(n, context) == *key,
}
}
fn keys_sequence<'x: 'y, 'y, K, F>(
key_sequence: &'y [K],
key_func: F,
mut node: Node<'x>,
) -> Option<Node<'x>>
where
F: for<'v> Fn(&'v Node<'x>, &'y ()) -> K + 'y,
K: Eq,
{
for key in key_sequence {
node = find_by_key(node, key, &key_func, &()).next()?;
}
Some(node)
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0597]: `key_func` does not live long enough
--> src/lib.rs:64:39
|
54 | fn keys_sequence<'x: 'y, 'y, K, F>(
| -- lifetime `'y` defined here
...
64 | node = find_by_key(node, key, &key_func, &()).next()?;
| -----------------------^^^^^^^^^------
| | |
| | borrowed value does not live long enough
| argument requires that `key_func` is borrowed for `'y`
...
68 | }
| - `key_func` dropped here while still borrowed
For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` due to previous error