Having Multiple Mutable References via Iterators
โ Rust ๐ 2026-04-09 ๐ค surdeus ๐๏ธ 5In section 8.1 of Brown Rust Book, there is the following question:
Determine whether the program will pass the compiler.
If it passes, write the expected output of the program if it were executed.fn main() { let mut v: Vec<i32> = vec![1, 2, 3]; let mut v2: Vec<&mut i32> = Vec::new(); for i in &mut v { v2.push(i); } *v2[0] = 5; let a = *v2[0]; let b = v[0]; println!("{a} {b}"); }
I thought that this obviously doesn't compile because we are taking multiple mutable references to v. But it turns out I was wrong. The program compiles fine.
Which is weird because in section 4.3 of the same book, they say the following:
Rustโs borrow checker does not contain different places for
a[0],a[1], and so on. It uses a single placea[_]that represents all indexes ofa.
They were talking about arrays in that section, but the same applies to vectors.
For example, this doesn't compile:
fn main() {
let mut v = vec![0, 1, 2, 3];
let x = &mut v[1];
let y = &mut v[2];
*x += *y;
println!("{v:?}");
}
Output:
error[E0499]: cannot borrow `v` as mutable more than once at a time
--> src/main.rs:4:18
|
3 | let x = &mut v[1];
| - first mutable borrow occurs here
4 | let y = &mut v[2];
| ^ second mutable borrow occurs here
5 | *x += *y;
| -------- first borrow later used here
|
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
For more information about this error, try `rustc --explain E0499`.
But this totally compiles:
fn main() {
let mut v = vec![0, 1, 2, 3];
let mut iter = v.iter_mut();
let x = iter.next().unwrap();
let y = iter.next().unwrap();
*x += *y;
*y += *x;
println!("{v:?}");
}
Output:
[1, 2, 2, 3]
So my question is:
How does this work?
Is the iterator doing something similar to split_at_mut for each element under the hood?
Disclaimer:
I'm a Rust beginner so sorry if the question is stupid or was answered before.
6 posts - 5 participants
๐ท๏ธ Rust_feed