Hi, I'm new to Rust and I love it, I'm currently learning about lifetimes but I can't figure out what's wrong with this snippet, can you please help me?
use std::result::Result as StdResult;
enum Error {
Unknown,
NoEventProviders,
}
type Result<T> = StdResult<T, Error>;
trait EventProvider {
fn wait_event(&mut self) -> Result<Event>;
fn poll_event(&mut self) -> Result<Option<Event>>;
}
trait Debuggee {}
enum EventInfo {}
enum Event<'a> {
External {
provider: &'a mut EventProvider,
},
Known {
info: EventInfo,
from: &'a Debuggee,
},
}
struct EventQueue<'a> {
providers: Vec<Box<EventProvider + 'a>>,
}
impl<'a> EventQueue<'a> {
fn wait_event(&mut self) -> Result<Event> {
match self.providers.len() {
0 => Err(Error::NoEventProviders),
1 => self.providers[0].wait_event(),
_ => {
loop {
if let Some(e) = try!(self.poll_event()) {
return Ok(e); // <-- if I change this line for unimplemented!() it compiles
}
}
}
}
}
fn poll_event(&mut self) -> Result<Option<Event>> {
for p in &mut self.providers {
if let Some(e) = try!(p.poll_event()) {
return Ok(Some(e));
}
}
Ok(None)
}
}
What I try to do is moving the Event from the Result that is returned from poll_event(..), if there's any. Thank you very much!
and then loop just has the effect of executing the statement several times, so this fails in the same way:
fn baz(&mut self) -> &str {
if let Some(e) = self.bar() {
return e;
}
self.bar();
""
}
but with a more understandable error message:
rustc 1.14.0 (e8a012324 2016-12-16)
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> <anon>:12:9
|
9 | if let Some(e) = self.bar() {
| ---- first mutable borrow occurs here
...
12 | self.bar();
| ^^^^ second mutable borrow occurs here
13 | ""
14 | }
| - first borrow ends here
So the first bar() call borrows self for the rest of the function. I have no idea why though.
Whatever the reason, the error message here could definitely be improved.
This comes up every once in awhile.
Returning a borrowed value extends the borrowing until the end of the function body.
I must admit that I don't fully understand why that is the case. But I believe the reason is that there might be destructors from "outer scopes" that are only run after returning.
I'd like to leave here this post as well, which really made me understand lifetimes, and also seems to explain why if I did return self.bar().unwrap(), things would just work: lifetimes span either a single expression or its enclosing block. [EDIT: Apparently, it's not single-expression lifetimes but the borrow checker analysis of control-flow]
I can't wait for nonlexical borrowing to be implemented. Definitely, I'm loving rust more day by day and can't wait to see it take over the world. Thank you!