Just for reference, I've built a far reduced example of the unsoundness that does not use trait objects. It uses the shared ref implementing DerefMut unsoundness; the same principle should apply to the mutable ref implementing Clone unsoundness.
// 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(&mut self) -> &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!
}
Here's a playpen: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=980b86aeb02c923e25937297e5018ef6
I don't think this has any persuasive bearing on the conversation, I just think it might be easier for people following along to understand what's happening with a short version.