I have some code that looks like this:
/// A kludge to satisfy the borrow checker on `RefCell` borrows.
/// We will never borrow the data we use this macro with mutably at any point,
/// and so it will have no reason to panic.
macro_rules! do_unchecked_borrow {
($cell: expr) => {
unsafe { $cell.try_borrow_unguarded().unwrap() }
}
}
// ...
// Handle = Rc<Node>
fn find_elements_by_attr_with_predicate<P>(&'a self, predicate: &'a P) -> Vec<&'a Handle>
where
P: Fn(&'a Attribute) -> bool,
{
let mut res = vec![];
match self.data {
NodeData::Document => {
for it in do_unchecked_borrow!(self.children).as_slice() {
res.append(&mut it.find_elements_by_attr_with_predicate(predicate))
}
}
NodeData::Element { ref attrs, .. } => {
if do_unchecked_borrow!(attrs).iter().any(|it| predicate(it)) {
res.push(self)
} else {
for it in do_unchecked_borrow!(self.children).as_slice() {
res.append(&mut it.find_elements_by_attr_with_predicate(predicate))
}
}
}
_ => {}
}
res
}
// The problem function.
fn find_element_by_attr_value(&'a self, value: &'a str) -> Option<&'a Handle> {
// pred is only used within this function.
let pred = move |attr: &Attribute| attr.value.as_ref() == value;
let a: Vec<&Rc<Node>> = self.find_elements_by_attr_with_predicate(&pred);
let b: Option<&&Rc<Node>> = a.get(0);
let c: Option<&Rc<Node>> = b.copied();
c // Compiler thinks c borrows pred somehow...
}
self
is of type Handle
(a.k.a Rc<Node>
).
The Vec
assigned to a
holds references to data held by self
. I don't believe there are any references to temporary data that would be invalidated when returning from any of these functions, but the compiler disagrees:
error[E0515]: cannot return value referencing local variable `pred`
--> endpoints/src/lib.rs:295:9
|
295 | self.find_elements_by_attr_with_predicate(&pred)
| ^ ----- `pred` is borrowed here
| _________|
| |
296 | | .get(0)
297 | | .copied()
| |_________________^ returns a value referencing data owned by the current function
I'm having a hard time understanding how pred
is borrowed by whatever is held in a
, b
or c
. What could I do to resolve this confusion?
Thanks for any help!