From 163ea4acd0e93d5a45ea44b42a999abe39d0a93f Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 28 Mar 2025 10:38:44 +0100 Subject: [PATCH] Add more tests for pin!(). Co-authored-by: Daniel Henry-Mantilla --- library/coretests/tests/pin_macro.rs | 11 ++++++++ tests/ui/pin-macro/pin_move.rs | 26 +++++++++++++++++++ tests/ui/pin-macro/pin_move.stderr | 38 ++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 tests/ui/pin-macro/pin_move.rs create mode 100644 tests/ui/pin-macro/pin_move.stderr diff --git a/library/coretests/tests/pin_macro.rs b/library/coretests/tests/pin_macro.rs index 639eab740c0b8..3174c91a6498b 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 0000000000000..0f6d34fad951f --- /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); + #[allow(unused_mut)] + let mut pointee = NotCopy(PhantomPinned); + pin!(pointee); + let _moved = pointee; + //~^ ERROR use of moved value +} + +fn b() { + struct NotCopy(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 0000000000000..c9b8ad9b2021f --- /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`, 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` implemented `Clone`, you could clone the value + --> $DIR/pin_move.rs:7:5 + | +LL | struct NotCopy(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`, which does not implement the `Copy` trait + | +note: if `b::NotCopy` implemented `Clone`, you could clone the value + --> $DIR/pin_move.rs:16:5 + | +LL | struct NotCopy(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`.