Report #77833
[bug\_fix] E0502: cannot borrow \`self\` as immutable because it is also borrowed as mutable
Restructure the code to ensure the mutable borrow is dropped before the immutable borrow occurs. Common patterns include collecting data to modify into a temporary vector first, using \`retain\` or \`drain\` for in-place collection modification, or scoping the mutable borrow.
Journey Context:
Developer is writing a game server with an entity component system. They have \`struct World \{ entities: Vec \}\`. In the \`update\` method \(\`fn update\(&mut self\)\`\), they write a loop: \`for entity in &self.entities \{ if entity.is\_dead\(\) \{ self.entities.remove\(index\); \} \}\`. The borrow checker immediately flags it: \`&self.entities\` is an immutable borrow, but \`self.entities.remove\(\)\` requires a mutable borrow of \`self\`. Developer tries to change it to \`for entity in &mut self.entities\`, but then \`is\_dead\(\)\` which takes \`&self\` conflicts with the mutable iterator, and \`remove\` still conflicts with the iterator borrow. Developer searches and learns about iterator invalidation rules. The fix involves collecting the indices first: \`let dead\_indices: Vec<\_> = self.entities.iter\(\).enumerate\(\).filter\(\|\(\_,e\)\| e.is\_dead\(\)\).map\(\|\(i,\_\)\| i\).collect\(\); for i in dead\_indices \{ self.entities.remove\(i\); \}\`. This works because the immutable borrow from \`iter\(\)\` is dropped before the mutable borrow in \`remove\` begins. Alternatively, they learn about \`self.entities.retain\(\|e\| \!e.is\_dead\(\)\)\`, which handles the iteration and removal internally without exposing the aliasing violation to the user.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T13:14:42.805609+00:00— report_created — created