How immutable is immutable?


#1

I just read this thread and I wonder if I can make a new local mutable variable of every object that is not mutable, not borrowed and owned.

In general the example confuses me, as I always thought that immutable really meant it is not possible to modify it.


#2

If you own a variable, you can mutate it. If it wasn’t declared with mut, you can reassign it with local let mut var = ... and mutate it anyway.

The main point here is ownership: as long as you own a variable (and you are not borrowing it at the moment) you can mutate it one way or another.

Update: I think I was not clear enough here. The “mutability” of an owned variable is property of the variable itself, not a data behind it. When you say let mut x = y; where y is not mutable, you create a new mutable variable x and bind it to the data bound to y. That is you can’t mutate a piece of data behind of immutable variable y, but you can do it behind mutable variable x. The data can be the same, but the variables (bindings) are different.

And, unless data in y is Copy, it is moved to x in the example, so you can’t use y after the let mut x = y;. That’s the base of Rust’s memory safety guarantee.


#3

Thanks for pointing that out.


#4

In general, mutable/immutable variables is a local lint against misuse.
Mutating something that you didn’t mark as mut? Are you sure? Not
mutating something you marked as mut? Are you sure?

There is no way in Rust to make something truly immutable other than
making it const or static… and even then the value may be copied and
mutated afterwards.


#5

Because of internal mutability (Mutex, Cell, RefCell, etc.), mutability really isn’t about mutability. It can be very helpful to think about mutability as if it were “exclusiveness”.

If you, exclusively, with no mutable or immutable borrows, own something, you can move it around and allow it to be mutated as much as you want in the future. A mutable borrow is exclusive, and thus allows direct mutation. An immutable borrow isn’t exclusive, thus no direct mutation, but you can always then have a control structure like a Mutex which schedules at runtime who is exclusively using an object, and thus a non-exclusive immutable borrow can mutate data.