Is miri's mutable aliasing guard too conservative?
⚓ Rust 📅 2025-06-20 👤 surdeus 👁️ 13Hello. This question is the return of this other one, but unfortunately the brilliant work-around suggested by Quinedot can't be applied to this new case.
I have some code that exhibits the following pattern, and fails under miri.
use core::cell::UnsafeCell;
struct Database {
state: UnsafeCell<Box<usize>>
}
struct Permission<'a> (&'a mut usize);
impl Permission<'_> {
fn increment(&mut self) {
*self.0 += 1;
}
}
impl Database {
fn new() -> Self {
Self{ state: UnsafeCell::new(Box::new(0))}
}
fn get_permission(&self) -> Option<Permission<'_>> {
//I know there needs to be other checks here so that multiple permissions aren't granted
// to the same state. That is elided because it's not relevant to this demonstration
Some(Permission(unsafe{ &mut *self.state.get() }))
}
fn cleanup_permission(&self, perm: Permission<'_>) {
drop(perm);
let state = unsafe{ &mut *self.state.get() };
**state += 1;
}
}
fn main() {
let db = Database::new();
let mut perm = db.get_permission().unwrap();
perm.increment();
db.cleanup_permission(perm);
}
If I separate the cleanup_permission method into two, there is no problem. However, the point of the cleanup code is that it must run immediately after the permission object is destroyed. So separating the API, ironically, makes it unsound.
My questions are:
- is my code actually UB? i.e. could the compiler reorder the drop somehow? Or is miri just being too conservative?
- Is there a work-around, given the new constraints?
Thanks for any thoughts or ideas.
1 post - 1 participant
🏷️ rust_feed