How can I avoid the `might be used` error in match cases

In the code excerpt below, I am not using mutable references at the same time, but the compiler believes that there is some issue about variable lifetime. How can I solve the problem?

fn update(&mut self, message: Message) -> Command<Message> {
    match self {
        Memories::Loaded(state) => match state.stage {
            Stage::ShowingEvents(ref mut displayer) => match message {
                Message::NextEvent => {
                    displayer.on_event += 1;
                    if displayer.on_event == displayer.events.lock().unwrap().len() {
                        // let state = state.to_owned();
                        // *self = Memories::Loading;
                        // return Command::perform(graduation::load_map(state), Message::Loaded);
                    } else {
                        let events: &MutexGuard<Vec<Event>> = &displayer.events.lock().unwrap();
                        if let None = events[displayer.on_event].get_image_handle() {
                            let handle = events[displayer.on_event].get_join_handle();
                            let state = std::mem::replace(self, Memories::Loading);
                            return Command::perform(
                                visiting::force_load(handle, state),
                                Message::FetchImage,
                            );
                        }
                    } // Line 439
                    visiting::load_images(state);
                }
            },
        },
    }
}

With this error:

error[E0499]: cannot borrow `*self` as mutable more than once at a time
   --> src\main.rs:433:71
    |
172 |             Memories::Loaded(state) => {
    |                              ----- first mutable borrow occurs here
...
430 |                                 let events = &displayer.events.lock().unwrap();
    |                                               -------------------------------- a temporary with access to the first borrow is created here ...
...
433 |                                     let state = std::mem::replace(self, Memories::Loading);
    |                                                                   ^^^^ second mutable borrow occurs here
...
439 |                             } // Line 439
    |                             - ... and the first borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `std::sync::MutexGuard`

But you are. And the compiler error pointed out exactly where.

I mean, is there anything I can change to make this code pass compile check?

Remove the & in this line.
let events: &MutexGuard<Vec<Event>> = &displayer.events.lock().unwrap();

and add explicit drop here:

let handle = events[displayer.on_event].get_join_handle();
drop(events);   // <--- Drop here so you release the lock sooner
let state = std::mem::replace(self, Memories::Loading);

It worked! Thank you!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.