diff options
Diffstat (limited to 'tests/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs')
-rw-r--r-- | tests/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/tests/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs b/tests/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs new file mode 100644 index 000000000..a5b856465 --- /dev/null +++ b/tests/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs @@ -0,0 +1,26 @@ +use std::cell::Cell; +use std::marker::PhantomPinned; +use std::pin::Pin; + +struct MyType<'a>(Cell<Option<&'a mut MyType<'a>>>, PhantomPinned); + +impl<'a> Clone for &'a mut MyType<'a> { + //~^ ERROR E0751 + fn clone(&self) -> &'a mut MyType<'a> { + self.0.take().unwrap() + } +} + +fn main() { + let mut unpinned = MyType(Cell::new(None), PhantomPinned); + let bad_addr = &unpinned as *const MyType<'_> as usize; + let mut p = Box::pin(MyType(Cell::new(Some(&mut unpinned)), PhantomPinned)); + + // p_mut1 is okay: it does not point to the bad_addr + let p_mut1: Pin<&mut MyType<'_>> = p.as_mut(); + assert_ne!(bad_addr, &*p_mut1 as *const _ as usize); + + // but p_mut2 does point to bad_addr! this is unsound + let p_mut2: Pin<&mut MyType<'_>> = p_mut1.clone(); + assert_eq!(bad_addr, &*p_mut2 as *const _ as usize); +} |