#value #mutable #constant #smart-pointers

mutable-constant

Mutable access to a constant value

2 unstable releases

0.1.0 May 12, 2023
0.0.1 May 11, 2023

#2596 in Rust patterns

43 downloads per month
Used in inscope

MIT/Apache

12KB
288 lines

mutable-constant

This crate provides a smart pointer that allows mutation even when the pointer is immutable.

This crate is very new. While it is unlikely to drastically change, it is not yet ready for production use.

Why would you want this?

Consider the following example:

let mut x = 0;
let y = &x;

// Error: `x` already borrowed as immutable
x += 1;

In this example, x is the clear owner of a value, and y wants to reference the value for later. In most cases, this error is justified, since y could change unexpectedly somewhere else. However, in this case, we want to know when x changes through y. The common solution is to use something like Cell or RefCell:

let x = Cell::new(0);
let y = &x;

x.set(x.get() + 1);

This works, but it's not very ergonomic. Cell and RefCell are also not very efficient, since they use runtime checks to ensure that the value is not borrowed mutably. There are a few situations where this is not acceptable:

  • You want the zero-cost abstraction of a basic reference
  • The value is generally immutable, but can change in specific situations. Other than those cases, the value should be immutable, and that fact should be enforced by the compiler.
  • You want a cleaner solution that clearly communicates your intent, including possible mutations and the lifetime of the value.

This crate provides a solution to these problems. It is not a RefCell alternative. Instead, it is a cheaper alternative to shared mutability in general, where mutable references are either compiler-enforced or explicitly unsafe. Here's how it could be used in the above case:

use mutable_constant::Mc;

let x = Mc::new(0);
let y = &x;

// This is unsafe, since `x` is already referenced
unsafe {
  *x.as_defiant_mut() += 1;
}

No runtime deps