Wrapper for unsafe multiple mutable reference
⚓ Rust 📅 2025-08-04 👤 surdeus 👁️ 10I am not good at English. Sorry if there are any funny expressions.
I have almost always failed with unsafe.
I'm sure I'm being stupid again. ![]()
So, please teach me loophole I am missing.
Background
Safe Rust does not allow multiple mutable references to same data.
I believe I also understand that this is important for our safety.
My idea (Probably stupid or pre-existing)
Today, I just had a thought. The reason why multiple mutable references are not allowed is to prevent conflicts between them. If so, how about creating a wrapper type for those mutable references and that guarantees their exclusion?
For example, like MutPair below. This type ensures the mutual exclusion of major and minor. However, if something like this were possible, someone would have already done it. In other words, there must be an unsafe escape route somewhere.
pub struct MutPair<'a, T, U> {
mode: bool,
major: &'a mut T,
minor: U,
}
impl<'a, T, U> MutPair<'a, T, U> {
pub fn new<F>(major: &'a mut T, f: F) -> Self
where
F: FnOnce(&'a mut T) -> U,
{
let mode = false;
let dup = unsafe { &mut *(major as *mut _) };
let minor = f(dup);
Self { mode, major, minor }
}
pub fn major(&mut self) -> &mut T {
assert!(self.mode);
self.major
}
pub fn minor(&mut self) -> &mut U {
assert!(!self.mode);
&mut self.minor
}
pub fn mode_major(&mut self) {
self.mode = true;
}
pub fn mode_minor(&mut self) {
self.mode = false;
}
}
Use case?
Probably wasteful, but I created a use case. Vector-like type SparseVec does not use memory if the element values are zero. When the mutable iterator of none_zeros_mut sets elements to zero, it removes those entries at the timing when the iterator is dropped.
3 posts - 2 participants
🏷️ Rust_feed