Turn an existing mutable variable to immutable in Rust

The immutability of Rust’s variables is a curse and a boon. It is a life saver when you are dealing with multi-threaded code. A curse when you want to modify the value.

So what do you do now? You add a mut after the let and make it mutable. Some time down the line (haha, get it?), you realize that you need the immutability. How do you turn a mutable variable into an immutable variable?

Shadow it Link to heading

Most of the times, the solution you are looking for is to shadow the mutable variable with the immutable variable.

Take the following code snippet for example:

File: test.rs

fn main() {
    let mut x = 1;
    x = x + 1;
    println!("{x}");
    let x = x;
    x = x + 3;
}

And, compiling…

$ rustc test.rs
error[E0384]: cannot assign twice to immutable variable `x`
 --> test.rs:6:5
  |
5 |     let x = x;
  |         -
  |         |
  |         first assignment to `x`
  |         help: consider making this binding mutable: `mut x`
6 |     x = x + 3;
  |     ^^^^^^^^^ cannot assign twice to immutable variable

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0384`.

(The unused variable warning from rustc is snipped.)

rustc is complaining that on line 6, column 5 of “test.rs”, it is referring to x as immutable.

But didn’t we declare x as mut on line 2? Yes, we did.

Now, check the 5th line. There I assigned x to itself, making use of Rust’s shadowing feature. The name x is now pointing to a different storage that is immutable, but has the value of &mut x assigned to it.

Info
Please note that in the above explanation, I only use “&mut x” to demonstrate that the value of mutable variable x gets copied. This does not mean that the new x will point to &mut x.

Conclusion Link to heading

To turn an existing mutable variable into an immutable variable (that Rust provides a thread-safe guarantee for), you can shadow the existing mutable variable with a new immutable variable.

let mut foo; // foo is mutable
let foo = foo; // foo shadows [mutable foo] and is now immutable

Please excuse the absence of comments. I do not want to enable any tracking (except for necessary embeds like YouTube and Twitter). I am not a web-dev and have no way of manually verifying if a provider tracks you or not.