2 unstable releases
0.1.0 | May 12, 2023 |
---|---|
0.0.1 | May 11, 2023 |
#2631 in Rust patterns
Used in inscope
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;
}