Crate alias [] [src]

alias offers some basic ways to mutate data while aliased.



let mut x = 0;

let y = alias::one(&mut x);
let z = y;

// now we can read/write through multiple references
y.set(y.get() + 2);
assert_eq!(z.get(), 12);
let mut x = [0, 0, 0, 0];

let y = alias::slice(&mut x);
let z = y;

// now we can read/write through multiple references
for i in 0..4 {
    y[i].set(y[i].get() + i);

assert_eq!(z[0].get(), 10);
assert_eq!(z[1].get(), 11);
assert_eq!(z[2].get(), 12);
assert_eq!(z[3].get(), 13);

How is this OK?

Rust's safety guarantees hinge around control how data is aliased/can be manipulated while aliased. Key to this are the & (shared/"immutable") and &mut (unique/mutable) reference types.

The latter essentially has the guarantee that if x: &mut T is accessible, then it is the only usable path to the T to which it points. This ensures arbitrary mutation is entirely safe, e.g. there's no way to invalidate other references because there are no other references.

On the other hand, &T references can be arbitrarily aliased (possibly in a large number of threads), and so mutation cannot occur by default. However, it can occur via specialised types that control what mutation can happen, such as std::cell::Cell<T>. That type is a plain wrapper around T that only works with a subset of possible Ts (T: Copy). These types all assume they have full control over access to their internal data: they mediate every interaction.

If one has unique access to some piece of data (&mut T), it is definitely safe to treat it as aliased (&T), but it is also safe to treat it as aliased and mutable (&Cell<T>). No other piece of code can be manipulating the T via any other path while the &mut T reference exists (and lifetimes ensures &Cell<T> cannot outlive it), so no other piece of code can do anything that violates the assumption that the Cell controls every interaction.

This also relies on TCell<T> being a valid transmute, that is, the layouts being identical. Strictly speaking, this isn't guaranteed, but it is unlikely for it to remain this way. (There's an additional factor of Cell theoretically having more layout optimisations possible due to the way it restricts access to its internals.)



Allow the mutable reference data to be mutated while aliased.


Allow the contents of the mutable slice data to be mutated while aliased.