I cannot figure out how to make the following code compile successfully. The first step was struggling through the lifetime annotation, however, I feel that it finally worked out.
The next step is the borrowing and lifetime around the HashMap
entry. I feel I am already too deep into the rabbit hole and need some guidance to get out.
use std::collections::HashMap;
struct Player {
id: u32,
}
struct Game<'a> {
black: &'a Player,
white: &'a Player,
win: bool,
timestamp: u32,
}
struct Base<'b> {
games: &'b mut Vec<Game<'b>>,
players: &'b mut HashMap<u32, Player>,
}
impl<'c> Base<'c> {
fn create_game(self, black_id: u32, white_id: u32, win: bool, timestamp: u32) -> &'c Game<'c> {
let black_player = self
.players
.entry(black_id)
.or_insert(Player { id: black_id });
let white_player = self
.players
.entry(white_id)
.or_insert(Player { id: white_id });
let game = Game {
black: &black_player,
white: &white_player,
win: win,
timestamp: timestamp,
};
self.games.push(game);
&self.games[0]
}
}
error[E0499]: cannot borrow `*self.players` as mutable more than once at a time
--> src/lib.rs:25:28
|
19 | impl<'c> Base<'c> {
| -- lifetime `'c` defined here
20 | fn create_game(self, black_id: u32, white_id: u32, win: bool, timestamp: u32) -> &'c Game<'c> {
21 | let black_player = self
| ____________________________-
| |____________________________|
| ||
22 | || .players
| ||____________________- first mutable borrow occurs here
23 | | .entry(black_id)
| |_____________________________- argument requires that `*self.players` is borrowed for `'c`
24 | .or_insert(Player { id: black_id });
25 | let white_player = self
| _____________________________^
26 | | .players
| |_____________________^ second mutable borrow occurs here
error[E0597]: `black_player` does not live long enough
--> src/lib.rs:31:20
|
19 | impl<'c> Base<'c> {
| -- lifetime `'c` defined here
...
31 | black: &black_player,
| ^^^^^^^^^^^^^ borrowed value does not live long enough
...
37 | self.games.push(game);
| --------------------- argument requires that `black_player` is borrowed for `'c`
38 | &self.games[0]
39 | }
| - `black_player` dropped here while still borrowed
error[E0597]: `white_player` does not live long enough
--> src/lib.rs:32:20
|
19 | impl<'c> Base<'c> {
| -- lifetime `'c` defined here
...
32 | white: &white_player,
| ^^^^^^^^^^^^^ borrowed value does not live long enough
...
37 | self.games.push(game);
| --------------------- argument requires that `white_player` is borrowed for `'c`
38 | &self.games[0]
39 | }
| - `white_player` dropped here while still borrowed