about summary refs log tree commit diff
path: root/tests/ui
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-09-10 20:29:08 +0200
committerGitHub <noreply@github.com>2025-09-10 20:29:08 +0200
commit868226b8b2f488196c37b90a110572bb8f3b391e (patch)
treea2405afa943d2c5c4d540bb8cbb6e976b8b239b2 /tests/ui
parentd061896a377bbc80837d99f8d71707e409e20d25 (diff)
parente4e7e71e3dbc88df948ffede96b8d76c675496e1 (diff)
downloadrust-868226b8b2f488196c37b90a110572bb8f3b391e.tar.gz
rust-868226b8b2f488196c37b90a110572bb8f3b391e.zip
Rollup merge of #146327 - Darksonn:pin-deref-tests, r=lcnr
Add tests for deref on pin

Tests split out from rust-lang/rust#145608.

r? `@lcnr`
Diffstat (limited to 'tests/ui')
-rw-r--r--tests/ui/deref/pin-deref-const.rs79
-rw-r--r--tests/ui/deref/pin-deref-const.stderr51
-rw-r--r--tests/ui/deref/pin-deref.rs76
-rw-r--r--tests/ui/deref/pin-deref.stderr51
-rw-r--r--tests/ui/deref/pin-impl-deref.rs40
-rw-r--r--tests/ui/deref/pin-impl-deref.stderr85
6 files changed, 382 insertions, 0 deletions
diff --git a/tests/ui/deref/pin-deref-const.rs b/tests/ui/deref/pin-deref-const.rs
new file mode 100644
index 00000000000..6ed00177b23
--- /dev/null
+++ b/tests/ui/deref/pin-deref-const.rs
@@ -0,0 +1,79 @@
+// The purpose of this file is to track the error messages from Pin and DerefMut interacting.
+//
+// Identical to `pin-deref.rs` except for using unstable `const fn`.
+
+//@ check-fail
+
+#![feature(const_convert)]
+#![feature(const_trait_impl)]
+
+use std::ops::DerefMut;
+use std::pin::Pin;
+
+struct MyUnpinType {}
+
+impl MyUnpinType {
+    const fn at_self(&self) {}
+    const fn at_mut_self(&mut self) {}
+}
+
+struct MyPinType(core::marker::PhantomPinned);
+
+impl MyPinType {
+    const fn at_self(&self) {}
+    const fn at_mut_self(&mut self) {}
+}
+
+const fn call_mut_ref_unpin(mut r_unpin: Pin<&mut MyUnpinType>) {
+    r_unpin.at_self();
+    r_unpin.at_mut_self();
+}
+
+const fn call_ref_unpin(mut r_unpin: Pin<&MyUnpinType>) {
+    r_unpin.at_self();
+    r_unpin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+}
+
+const fn call_mut_ref_pin(mut r_pin: Pin<&mut MyPinType>) {
+    r_pin.at_self();
+    r_pin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+}
+
+const fn call_ref_pin(mut r_pin: Pin<&MyPinType>) {
+    r_pin.at_self();
+    r_pin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+}
+
+const fn coerce_unpin_rr<'a>(mut r_unpin: &'a mut Pin<&MyUnpinType>) -> &'a MyUnpinType {
+    r_unpin
+}
+
+const fn coerce_unpin_rm<'a>(mut r_unpin: &'a mut Pin<&MyUnpinType>) -> &'a mut MyUnpinType {
+    r_unpin //~ ERROR: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+}
+
+const fn coerce_unpin_mr<'a>(mut r_unpin: &'a mut Pin<&mut MyUnpinType>) -> &'a MyUnpinType {
+    r_unpin
+}
+
+const fn coerce_unpin_mm<'a>(mut r_unpin: &'a mut Pin<&mut MyUnpinType>) -> &'a mut MyUnpinType {
+    r_unpin
+}
+
+const fn coerce_pin_rr<'a>(mut r_pin: &'a mut Pin<&MyPinType>) -> &'a MyPinType {
+    r_pin
+}
+
+const fn coerce_pin_rm<'a>(mut r_pin: &'a mut Pin<&MyPinType>) -> &'a mut MyPinType {
+    r_pin //~ ERROR: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+}
+
+const fn coerce_pin_mr<'a>(mut r_pin: &'a mut Pin<&mut MyPinType>) -> &'a MyPinType {
+    r_pin
+}
+
+const fn coerce_pin_mm<'a>(mut r_pin: &'a mut Pin<&mut MyPinType>) -> &'a mut MyPinType {
+    r_pin //~ ERROR: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+}
+
+fn main() {}
diff --git a/tests/ui/deref/pin-deref-const.stderr b/tests/ui/deref/pin-deref-const.stderr
new file mode 100644
index 00000000000..caa270e64ff
--- /dev/null
+++ b/tests/ui/deref/pin-deref-const.stderr
@@ -0,0 +1,51 @@
+error[E0596]: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+  --> $DIR/pin-deref-const.rs:34:5
+   |
+LL |     r_unpin.at_mut_self();
+   |     ^^^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyUnpinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+  --> $DIR/pin-deref-const.rs:39:5
+   |
+LL |     r_pin.at_mut_self();
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+  --> $DIR/pin-deref-const.rs:44:5
+   |
+LL |     r_pin.at_mut_self();
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+  --> $DIR/pin-deref-const.rs:52:5
+   |
+LL |     r_unpin
+   |     ^^^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyUnpinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+  --> $DIR/pin-deref-const.rs:68:5
+   |
+LL |     r_pin
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+  --> $DIR/pin-deref-const.rs:76:5
+   |
+LL |     r_pin
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut MyPinType>`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/deref/pin-deref.rs b/tests/ui/deref/pin-deref.rs
new file mode 100644
index 00000000000..180831c9bc6
--- /dev/null
+++ b/tests/ui/deref/pin-deref.rs
@@ -0,0 +1,76 @@
+// The purpose of this file is to track the error messages from Pin and DerefMut interacting.
+//
+// Identical to `pin-deref-const.rs` except for being stable and not using `const fn`.
+
+//@ check-fail
+
+use std::ops::DerefMut;
+use std::pin::Pin;
+
+struct MyUnpinType {}
+
+impl MyUnpinType {
+    fn at_self(&self) {}
+    fn at_mut_self(&mut self) {}
+}
+
+struct MyPinType(core::marker::PhantomPinned);
+
+impl MyPinType {
+    fn at_self(&self) {}
+    fn at_mut_self(&mut self) {}
+}
+
+fn call_mut_ref_unpin(mut r_unpin: Pin<&mut MyUnpinType>) {
+    r_unpin.at_self();
+    r_unpin.at_mut_self();
+}
+
+fn call_ref_unpin(mut r_unpin: Pin<&MyUnpinType>) {
+    r_unpin.at_self();
+    r_unpin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+}
+
+fn call_mut_ref_pin(mut r_pin: Pin<&mut MyPinType>) {
+    r_pin.at_self();
+    r_pin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+}
+
+fn call_ref_pin(mut r_pin: Pin<&MyPinType>) {
+    r_pin.at_self();
+    r_pin.at_mut_self(); //~ ERROR: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+}
+
+fn coerce_unpin_rr<'a>(mut r_unpin: &'a mut Pin<&MyUnpinType>) -> &'a MyUnpinType {
+    r_unpin
+}
+
+fn coerce_unpin_rm<'a>(mut r_unpin: &'a mut Pin<&MyUnpinType>) -> &'a mut MyUnpinType {
+    r_unpin //~ ERROR: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+}
+
+fn coerce_unpin_mr<'a>(mut r_unpin: &'a mut Pin<&mut MyUnpinType>) -> &'a MyUnpinType {
+    r_unpin
+}
+
+fn coerce_unpin_mm<'a>(mut r_unpin: &'a mut Pin<&mut MyUnpinType>) -> &'a mut MyUnpinType {
+    r_unpin
+}
+
+fn coerce_pin_rr<'a>(mut r_pin: &'a mut Pin<&MyPinType>) -> &'a MyPinType {
+    r_pin
+}
+
+fn coerce_pin_rm<'a>(mut r_pin: &'a mut Pin<&MyPinType>) -> &'a mut MyPinType {
+    r_pin //~ ERROR: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+}
+
+fn coerce_pin_mr<'a>(mut r_pin: &'a mut Pin<&mut MyPinType>) -> &'a MyPinType {
+    r_pin
+}
+
+fn coerce_pin_mm<'a>(mut r_pin: &'a mut Pin<&mut MyPinType>) -> &'a mut MyPinType {
+    r_pin //~ ERROR: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+}
+
+fn main() {}
diff --git a/tests/ui/deref/pin-deref.stderr b/tests/ui/deref/pin-deref.stderr
new file mode 100644
index 00000000000..71277a10cdf
--- /dev/null
+++ b/tests/ui/deref/pin-deref.stderr
@@ -0,0 +1,51 @@
+error[E0596]: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+  --> $DIR/pin-deref.rs:31:5
+   |
+LL |     r_unpin.at_mut_self();
+   |     ^^^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyUnpinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+  --> $DIR/pin-deref.rs:36:5
+   |
+LL |     r_pin.at_mut_self();
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+  --> $DIR/pin-deref.rs:41:5
+   |
+LL |     r_pin.at_mut_self();
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyUnpinType>` as mutable
+  --> $DIR/pin-deref.rs:49:5
+   |
+LL |     r_unpin
+   |     ^^^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyUnpinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&MyPinType>` as mutable
+  --> $DIR/pin-deref.rs:65:5
+   |
+LL |     r_pin
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&MyPinType>`
+
+error[E0596]: cannot borrow data in dereference of `Pin<&mut MyPinType>` as mutable
+  --> $DIR/pin-deref.rs:73:5
+   |
+LL |     r_pin
+   |     ^^^^^ cannot borrow as mutable
+   |
+   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut MyPinType>`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/deref/pin-impl-deref.rs b/tests/ui/deref/pin-impl-deref.rs
new file mode 100644
index 00000000000..b1dc8dea3f2
--- /dev/null
+++ b/tests/ui/deref/pin-impl-deref.rs
@@ -0,0 +1,40 @@
+// The purpose of this file is to track the error messages from Pin and DerefMut interacting.
+
+//@ check-fail
+
+use std::ops::DerefMut;
+use std::pin::Pin;
+
+struct MyUnpinType {}
+
+impl MyUnpinType {
+    fn at_self(&self) {}
+    fn at_mut_self(&mut self) {}
+}
+
+struct MyPinType(core::marker::PhantomPinned);
+
+impl MyPinType {
+    fn at_self(&self) {}
+    fn at_mut_self(&mut self) {}
+}
+
+fn impl_deref_mut(_: impl DerefMut) {}
+fn unpin_impl_ref(r_unpin: Pin<&MyUnpinType>) {
+    impl_deref_mut(r_unpin)
+    //~^ ERROR: the trait bound `Pin<&MyUnpinType>: DerefMut` is not satisfied
+}
+fn unpin_impl_mut(r_unpin: Pin<&mut MyUnpinType>) {
+    impl_deref_mut(r_unpin)
+}
+fn pin_impl_ref(r_pin: Pin<&MyPinType>) {
+    impl_deref_mut(r_pin)
+    //~^ ERROR: `PhantomPinned` cannot be unpinned
+    //~| ERROR: the trait bound `Pin<&MyPinType>: DerefMut` is not satisfied
+}
+fn pin_impl_mut(r_pin: Pin<&mut MyPinType>) {
+    impl_deref_mut(r_pin)
+    //~^ ERROR: `PhantomPinned` cannot be unpinned
+}
+
+fn main() {}
diff --git a/tests/ui/deref/pin-impl-deref.stderr b/tests/ui/deref/pin-impl-deref.stderr
new file mode 100644
index 00000000000..106654641a1
--- /dev/null
+++ b/tests/ui/deref/pin-impl-deref.stderr
@@ -0,0 +1,85 @@
+error[E0277]: the trait bound `Pin<&MyUnpinType>: DerefMut` is not satisfied
+  --> $DIR/pin-impl-deref.rs:24:20
+   |
+LL |     impl_deref_mut(r_unpin)
+   |     -------------- ^^^^^^^ the trait `DerefMut` is not implemented for `Pin<&MyUnpinType>`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: required for `Pin<&MyUnpinType>` to implement `DerefMut`
+note: required by a bound in `impl_deref_mut`
+  --> $DIR/pin-impl-deref.rs:22:27
+   |
+LL | fn impl_deref_mut(_: impl DerefMut) {}
+   |                           ^^^^^^^^ required by this bound in `impl_deref_mut`
+help: consider mutably borrowing here
+   |
+LL |     impl_deref_mut(&mut r_unpin)
+   |                    ++++
+
+error[E0277]: the trait bound `Pin<&MyPinType>: DerefMut` is not satisfied
+  --> $DIR/pin-impl-deref.rs:31:20
+   |
+LL |     impl_deref_mut(r_pin)
+   |     -------------- ^^^^^ the trait `DerefMut` is not implemented for `Pin<&MyPinType>`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: required for `Pin<&MyPinType>` to implement `DerefMut`
+note: required by a bound in `impl_deref_mut`
+  --> $DIR/pin-impl-deref.rs:22:27
+   |
+LL | fn impl_deref_mut(_: impl DerefMut) {}
+   |                           ^^^^^^^^ required by this bound in `impl_deref_mut`
+help: consider mutably borrowing here
+   |
+LL |     impl_deref_mut(&mut r_pin)
+   |                    ++++
+
+error[E0277]: `PhantomPinned` cannot be unpinned
+  --> $DIR/pin-impl-deref.rs:31:20
+   |
+LL |     impl_deref_mut(r_pin)
+   |     -------------- ^^^^^ within `MyPinType`, the trait `Unpin` is not implemented for `PhantomPinned`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: consider using the `pin!` macro
+           consider using `Box::pin` if you need to access the pinned value outside of the current scope
+note: required because it appears within the type `MyPinType`
+  --> $DIR/pin-impl-deref.rs:15:8
+   |
+LL | struct MyPinType(core::marker::PhantomPinned);
+   |        ^^^^^^^^^
+   = note: required for `Pin<&MyPinType>` to implement `DerefMut`
+note: required by a bound in `impl_deref_mut`
+  --> $DIR/pin-impl-deref.rs:22:27
+   |
+LL | fn impl_deref_mut(_: impl DerefMut) {}
+   |                           ^^^^^^^^ required by this bound in `impl_deref_mut`
+
+error[E0277]: `PhantomPinned` cannot be unpinned
+  --> $DIR/pin-impl-deref.rs:36:20
+   |
+LL |     impl_deref_mut(r_pin)
+   |     -------------- ^^^^^ within `MyPinType`, the trait `Unpin` is not implemented for `PhantomPinned`
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = note: consider using the `pin!` macro
+           consider using `Box::pin` if you need to access the pinned value outside of the current scope
+note: required because it appears within the type `MyPinType`
+  --> $DIR/pin-impl-deref.rs:15:8
+   |
+LL | struct MyPinType(core::marker::PhantomPinned);
+   |        ^^^^^^^^^
+   = note: required for `Pin<&mut MyPinType>` to implement `DerefMut`
+note: required by a bound in `impl_deref_mut`
+  --> $DIR/pin-impl-deref.rs:22:27
+   |
+LL | fn impl_deref_mut(_: impl DerefMut) {}
+   |                           ^^^^^^^^ required by this bound in `impl_deref_mut`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.