Hello!
I have a situation similar to the following, where I want to provide a reference, instead of a guard (Ref<'a, ()> in this case), which can be cumbersome to work with.
use std::cell::{RefCell, Ref};
struct Foo<'a> {
data: &'a RefCell<()>,
guard: Option<Ref<'a, ()>>
}
impl<'a> Iterator for Foo<'a> {
type Item = &'a ();
fn next<'b>(&'b mut self) -> Option<&'a ()> {
self.guard = self.data.try_borrow().ok();
if let Some(x) = &self.guard {
Some(&**x)
} else {
None
}
}
}
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/lib.rs:12:26
|
12 | if let Some(x) = &self.guard {
| ^^^^^^^^^^^
|
Iterators won't do the job your after.
The return item from next is never bound to the life of the iterator (The variable storing the iterator not 'a) or borrow ('b)
Every time next is called self.guard gets replaced so you can't take a borrow from it that will last.
Your "fix" link shows 'b:'a swap it around and it fails. With 'b:'a you don't get to call next a second time until the first result is dropped.
Maybe something like for_each(cb: impl Fn(&()) ) would do.
Note the lifetime you add in structure is also off; ('static in unit type)
No direct link between 'a and 't. Variance allows 'a to be used.
When you deref guard the returned reference is restricted to that borrow (ie 'b)
Edit: Was reading Ref when came up with above, but is wrong (after trying small bit of code.) Ref lifetime parameter is set at/from call to try_borrow (or borrow)
Like whar @jonh said, you can't use the Iterator interface for this, you can use the streaming iterator interface for this however, which can be found here.