After learning Rust for a while, I started to think that I understood its ownership/borrowing mechanism, but the next example makes me really puzzled. I am playing with rust-sdl2:
extern crate sdl2;
use sdl2::Sdl;
use sdl2::event::Event;
use sdl2::render::Renderer;
struct SdlDriver<'a> {
sdl_ctx : Sdl,
renderer : Renderer<'a>
}
impl<'a> SdlDriver<'a> {
fn event_pump(&self) -> sdl2::event::EventPump {
self.sdl_ctx.event_pump()
}
fn draw_rect(&mut self, x: i32, y: i32) {
let mut drawer = self.renderer.drawer();
drawer.draw_rect(sdl2::rect::Rect::new(x-20, y-20, 40, 40));
drawer.present();
}
fn event_loop(&mut self) {
let mut event_pump = self.event_pump();
loop {
let event = event_pump.wait_event();
match event {
Event::Quit {..} => { break },
Event::MouseMotion { x, y, .. } => {
self.draw_rect(x, y);
},
_ => ()
}
}
}
}
fn main() {
}
The compiler shows me the error:
main.rs:32:25: 32:29 error: cannot borrow `*self` as mutable because it is also borrowed as immutable
main.rs:32 self.draw_rect(x, y);
^~~~
main.rs:24:34: 24:38 note: previous borrow of `*self` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `*self` until the borrow ends
main.rs:24 let mut event_pump = self.event_pump();
^~~~
main.rs:37:10: 37:10 note: previous borrow ends here
main.rs:23 fn event_loop(&mut self) {
...
main.rs:37 }
^
As I understand it, the call to self.event_pump() should temporarily borrow *self, return EventPump struct which is now owned by event_loop(), and then release *self. But it looks like *self is borrowed for the entire lifetime of event_pump. Why?
For comparison, when I call methods without returning results, like
self.draw_rect(x, y);
self.draw_rect(x, y);
everything works fine, *self is released immediately after every call.
Another thing I don't understand is why *self is borrowed (with star)? event_loop(&mut self) already borrows self from its caller, why is it required to borrow *self here?
How should the example above be rewritten to satisfy Rust's borrow checker?