Is there a way to declare a variable immutable in a meaningful way?

267 views Asked by At

Up until today, I thought declaring a variable without mut made sure it can not be changed after initialization.

I thought this was great because I always resented the way that const in C and C++ didn't guarantee anything.

I just found out I was wrong: Rust allows internal mutability (see std::cell). It gives you some guarantees, but is not what I expect and wish for when I hear immutable.

Is there a way to declare something "really immutable"?

1

There are 1 answers

3
oli_obk On BEST ANSWER

Preventing interior mutability is impossible in run-time evaluated code (Constant evaluation makes this easy, there's no mutation of any kind). Any type you use that you don't have control over might be using unsafe code to achieve interior mutability. To prevent the most common cases you can use a so called "marker trait". This trait has no other purpose but to allow you to differentiate between types that implement your trait and types that don't.

#![feature(optin_builtin_traits)]

use std::cell::{RefCell, Cell, UnsafeCell};
use std::sync::Mutex;

unsafe trait ReallyImmutable {}

unsafe impl ReallyImmutable for .. {}
impl<T> !ReallyImmutable for RefCell<T> {}
impl<T> !ReallyImmutable for Cell<T> {}
impl<T> !ReallyImmutable for UnsafeCell<T> {}
impl<T> !ReallyImmutable for Mutex<T> {}
impl<'a, T> !ReallyImmutable for &'a mut T {}
impl<T> !ReallyImmutable for *mut T {}
impl<T> !ReallyImmutable for *const T {}

This has of course the disadvantage of requiring you to blacklist interior mutability instead of white-listing immutable types. So you might always miss something.