diff options
| -rw-r--r-- | library/coretests/tests/pin_macro.rs | 11 | ||||
| -rw-r--r-- | tests/ui/pin-macro/pin_move.rs | 26 | ||||
| -rw-r--r-- | tests/ui/pin-macro/pin_move.stderr | 38 |
3 files changed, 75 insertions, 0 deletions
diff --git a/library/coretests/tests/pin_macro.rs b/library/coretests/tests/pin_macro.rs index 639eab740c0..3174c91a649 100644 --- a/library/coretests/tests/pin_macro.rs +++ b/library/coretests/tests/pin_macro.rs @@ -47,3 +47,14 @@ fn temp_lifetime() { } async fn foo(_: &mut usize) {} } + +#[test] +fn transitive_extension() { + async fn temporary() {} + + // `pin!` witnessed in the wild being used like this, even if it yields + // a `Pin<&mut &mut impl Unpin>`; it does work because `pin!` + // happens to transitively extend the lifespan of `temporary()`. + let p = pin!(&mut temporary()); + let _use = p; +} diff --git a/tests/ui/pin-macro/pin_move.rs b/tests/ui/pin-macro/pin_move.rs new file mode 100644 index 00000000000..0f6d34fad95 --- /dev/null +++ b/tests/ui/pin-macro/pin_move.rs @@ -0,0 +1,26 @@ +//@ edition:2024 + +use core::marker::PhantomPinned; +use core::pin::pin; + +fn a() { + struct NotCopy<T>(T); + #[allow(unused_mut)] + let mut pointee = NotCopy(PhantomPinned); + pin!(pointee); + let _moved = pointee; + //~^ ERROR use of moved value +} + +fn b() { + struct NotCopy<T>(T); + let mut pointee = NotCopy(PhantomPinned); + pin!(*&mut pointee); + //~^ ERROR cannot move + let _moved = pointee; +} + +fn main() { + a(); + b(); +} diff --git a/tests/ui/pin-macro/pin_move.stderr b/tests/ui/pin-macro/pin_move.stderr new file mode 100644 index 00000000000..c9b8ad9b202 --- /dev/null +++ b/tests/ui/pin-macro/pin_move.stderr @@ -0,0 +1,38 @@ +error[E0382]: use of moved value: `pointee` + --> $DIR/pin_move.rs:11:18 + | +LL | let mut pointee = NotCopy(PhantomPinned); + | ----------- move occurs because `pointee` has type `a::NotCopy<PhantomPinned>`, which does not implement the `Copy` trait +LL | pin!(pointee); + | ------- value moved here +LL | let _moved = pointee; + | ^^^^^^^ value used here after move + | +note: if `a::NotCopy<PhantomPinned>` implemented `Clone`, you could clone the value + --> $DIR/pin_move.rs:7:5 + | +LL | struct NotCopy<T>(T); + | ^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | pin!(pointee); + | ------- you could clone this value + +error[E0507]: cannot move out of a mutable reference + --> $DIR/pin_move.rs:18:10 + | +LL | pin!(*&mut pointee); + | ^^^^^^^^^^^^^ move occurs because value has type `b::NotCopy<PhantomPinned>`, which does not implement the `Copy` trait + | +note: if `b::NotCopy<PhantomPinned>` implemented `Clone`, you could clone the value + --> $DIR/pin_move.rs:16:5 + | +LL | struct NotCopy<T>(T); + | ^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +LL | let mut pointee = NotCopy(PhantomPinned); +LL | pin!(*&mut pointee); + | ------------- you could clone this value + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0382, E0507. +For more information about an error, try `rustc --explain E0382`. |
