// A !Unpin type to reference
struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, PhantomPinned);
impl<'a> DerefMut for &'a MyType<'a> {
fn deref_mut<'this>(&'this mut self) -> &'this mut MyType<'a> {
self.0.replace(None).unwrap()
}
}
fn main() {
let mut unpinned = Box::new(MyType(Cell::new(None), PhantomPinned));
let pinned = Box::pin(MyType(Cell::new(Some(&mut unpinned)),
PhantomPinned);
let mut pinned_ref: Pin<&MyType<'_>> = pinned.as_ref();
// call the unsound DerefMut impl
let pinned_mut: Pin<&mut MyType<'_>> = pinned_ref.as_mut();
// pinned_mut points to the address at `unpinned`, which
// can be moved in the future. UNSOUND!
Links
Background and summary
// A !Unpin type to reference
struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, PhantomPinned);
impl<'a> DerefMut for &'a MyType<'a> {
fn deref_mut<'this>(&'this mut self) -> &'this mut MyType<'a> {
self.0.replace(None).unwrap()
}
}
fn main() {
let mut unpinned = Box::new(MyType(Cell::new(None), PhantomPinned));
let pinned = Box::pin(MyType(Cell::new(Some(&mut unpinned)),
PhantomPinned);
let mut pinned_ref: Pin<&MyType<'_>> = pinned.as_ref();
// call the unsound DerefMut impl
let pinned_mut: Pin<&mut MyType<'_>> = pinned_ref.as_mut();
// pinned_mut points to the address at `unpinned`, which
// can be moved in the future. UNSOUND!