A tricky part about Rust's immutability is this:
fn f() {
let list = Vec::new();
g(list);
}
fn g(mut list: Vec<i32>) {
list.push(1);
list = Vec::new();
}
We're changing the list that was immutable.
Maybe this seems weird for several reasons: 1) wasn't the list an immutable object? 2) why doesn't that work with borrows? 3) why does Rust let me change immutable to mutable?
The first thing to remember is that, just like other languages such as Java, it's the reference that is immutable, not the object itself. Just, unlike Java, this also applies recursively to anything within the reference.
Another thing to remember is that, if you pass an object to another method, you're either passing sole ownership, or you're sending a copy.
If function f passes sole ownership of the list to g, then f cannot have any references anymore. Whatever g does, it won't affect f. So it's no problem if g makes it mutable.
And if f passes a copy, of course it won't care what g does with that; it still has it's own version.