-
Notifications
You must be signed in to change notification settings - Fork 390
Closed
Description
When running this code under Miri (playground link):
use std::cell::UnsafeCell;
use std::marker::PhantomPinned;
use std::pin::Pin;
pub struct SelfReferential {
number: UnsafeCell<i32>,
number_mut_ref: Option<*const UnsafeCell<i32>>,
_pinned: PhantomPinned,
}
impl SelfReferential {
pub fn new() -> Self {
Self {
number: UnsafeCell::new(0),
number_mut_ref: None,
_pinned: PhantomPinned,
}
}
pub fn initialize(self: Pin<&mut Self>, number: i32) {
let this = unsafe { self.get_unchecked_mut() };
this.number = UnsafeCell::new(number);
this.number_mut_ref = Some(&this.number);
}
pub fn add_one(self: Pin<&mut Self>) {
let this = unsafe { self.get_unchecked_mut() };
// If this line that is seemingly a no-op is commented, this code fails.
unsafe { &*this.number.get() };
let number_ptr = this.number_mut_ref.unwrap();
*unsafe { &mut *(&*number_ptr).get() } += 1;
}
}
fn main() {
let v = SelfReferential::new();
pin_utils::pin_mut!(v);
v.as_mut().initialize(5);
v.as_mut().add_one();
}
No errors are produced. However, if that line is commented, there is a violation of stacked borrows.
What is the intended behaviour here? And is this a valid way to implement safe self-referential types?
Metadata
Metadata
Assignees
Labels
No labels