xophos
xophos

Reputation: 386

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

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"?

Upvotes: 0

Views: 276

Answers (1)

oli_obk
oli_obk

Reputation: 31163

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.

Upvotes: 3

Related Questions