Skip to content
rust: cannot borrow `*self` as mutable because it is also borrowed as immutable
question1 min read129 viewsOct 17, 2026

rust: cannot borrow `*self` as mutable because it is also borrowed as immutable

Olivia Martin@liv_codes

October 17, 2026 · 1 min read

#2 in Rubber Duck Club

129 views4 comments

making the pong game for @tomasz_k (long story) and im stuck on the borrow checker. i have a game struct with a list of entities and i want to update each one, but update needs to call a method on self

struct Game {
    items: Vec<Entity>,
    score: u32,
}

impl Game {
    fn tick(&mut self) {
        for item in self.items.iter() {
            self.update(item);
        }
    }

    fn update(&mut self, item: &Entity) {
        // moves the item, maybe changes score
    }
}

i kind of get WHY (im iterating over items while self could change items) but i dont know the normal way to fix it. clone the vec? that feels wrong

Accepted answer

Arjun Mehta#1 in Rubber Duck Club3 likes

Classic one. The loop holds a borrow of self.items, and update wants all of self mutably, which includes items. A few normal fixes: 1. Make update not take &mut self. If it only needs the score, pass that: fn update(item: &mut Entity, score: &mut u32) then for item in self.items.iter_mut() { Self::update(item, &mut self.score); } The compiler is fine with borrowing two different fields at the same time. 2. Loop by index: for i in 0..self.items.len() and use self.items[i]. Works, but it gets ugly fast. 3. Take the vec out temporarily: let mut items = std::mem::take(&mut self.items); loop over it, then put it back. Useful when update really needs the whole self. Option 1 is usually the idiomatic answer: split the data so each function borrows only what it needs.

View in the thread

Written by

Olivia Martin

final year cs student @ toronto. looking for a summer internship (hire me pls). currently obsessed with rust and making my resume not look like a resume

Get the best of #rubber-duck-club weekly

One email each Monday with the most useful posts. No spam; unsubscribe in one click.

Comments

4

Sign in to join the conversation.

Sign in to comment

Accepted answer

Arjun Mehta@arjunmehta#1 in Rubber Duck Club
Classic one. The loop holds a borrow of self.items, and update wants all of self mutably, which includes items. A few normal fixes: 1. Make update not take &mut self. If it only needs the score, pass that: fn update(item: &mut Entity, score: &mut u32) then for item in self.items.iter_mut() { Self::update(item, &mut self.score); } The compiler is fine with borrowing two different fields at the same time. 2. Loop by index: for i in 0..self.items.len() and use self.items[i]. Works, but it gets ugly fast. 3. Take the vec out temporarily: let mut items = std::mem::take(&mut self.items); loop over it, then put it back. Useful when update really needs the whole self. Option 1 is usually the idiomatic answer: split the data so each function borrows only what it needs.
3 net votes
Olivia Martin@liv_codes#2 in Rubber Duck Club
option 1 worked!! passing the score separately and the compiler just. accepted it. the borrow checker is way less scary once u realise its about fields
0 net votes
Tomasz Kowalski@tomasz_k#3 in Rubber Duck Club
Pong for me, with borrow checker. This is more effort than my last three Java projects. I am honoured.
0 net votes
Olivia Martin@liv_codes#2 in Rubber Duck Club
u better be. there's a paddle named after u. it moves slowly and judges everyone
0 net votes