about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKevin Reid <kpreid@switchb.org>2024-12-21 17:13:52 -0800
committerKevin Reid <kpreid@switchb.org>2024-12-22 11:18:56 -0800
commit5c04151c6cea29398b786b3fa781ec2f8f5ed1da (patch)
treea063fc7a59a4f7045fc8dcfcb9f38c942259237b
parent13170cd787cb733ed24842ee825bcbd98dc01476 (diff)
downloadrust-5c04151c6cea29398b786b3fa781ec2f8f5ed1da.tar.gz
rust-5c04151c6cea29398b786b3fa781ec2f8f5ed1da.zip
Implement `PointerLike` for `isize`, `NonNull`, `Cell`, `UnsafeCell`, and `SyncUnsafeCell`.
Implementing `PointerLike` for `UnsafeCell` enables the possibility of
interior mutable `dyn*` values. Since this means potentially exercising
new codegen behavior, I added a test for it in `tests/ui/dyn-star/cell.rs`.

Also updated UI tests to account for the `isize` implementation changing
error messages.
-rw-r--r--library/core/src/cell.rs11
-rw-r--r--library/core/src/marker.rs1
-rw-r--r--library/core/src/ptr/non_null.rs4
-rw-r--r--tests/ui/dyn-star/cell.rs34
-rw-r--r--tests/ui/dyn-star/error.rs2
-rw-r--r--tests/ui/dyn-star/float-as-dyn-star.stderr4
6 files changed, 53 insertions, 3 deletions
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index cfa4c1fb564..306d565a77e 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -252,7 +252,7 @@
 
 use crate::cmp::Ordering;
 use crate::fmt::{self, Debug, Display};
-use crate::marker::{PhantomData, Unsize};
+use crate::marker::{PhantomData, PointerLike, Unsize};
 use crate::mem;
 use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
 use crate::pin::PinCoerceUnsized;
@@ -677,6 +677,9 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Cell<U>> for Cell<T> {}
 
+#[unstable(feature = "pointer_like_trait", issue = "none")]
+impl<T: PointerLike> PointerLike for Cell<T> {}
+
 impl<T> Cell<[T]> {
     /// Returns a `&[Cell<T>]` from a `&Cell<[T]>`
     ///
@@ -2258,6 +2261,9 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}
 
+#[unstable(feature = "pointer_like_trait", issue = "none")]
+impl<T: PointerLike> PointerLike for UnsafeCell<T> {}
+
 /// [`UnsafeCell`], but [`Sync`].
 ///
 /// This is just an `UnsafeCell`, except it implements `Sync`
@@ -2364,6 +2370,9 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell
 //#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
 impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
 
+#[unstable(feature = "pointer_like_trait", issue = "none")]
+impl<T: PointerLike> PointerLike for SyncUnsafeCell<T> {}
+
 #[allow(unused)]
 fn assert_coerce_unsized(
     a: UnsafeCell<&i32>,
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 3d79706f8ec..b8613ce44c5 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -997,6 +997,7 @@ pub trait PointerLike {}
 marker_impls! {
     #[unstable(feature = "pointer_like_trait", issue = "none")]
     PointerLike for
+        isize,
         usize,
         {T} &T,
         {T} &mut T,
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 6b601405e1c..97b0020d53c 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -1548,6 +1548,10 @@ impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: U
 #[stable(feature = "pin", since = "1.33.0")]
 unsafe impl<T: ?Sized> PinCoerceUnsized for NonNull<T> {}
 
+#[unstable(feature = "pointer_like_trait", issue = "none")]
+#[cfg(not(bootstrap))]
+impl<T> core::marker::PointerLike for NonNull<T> {}
+
 #[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> fmt::Debug for NonNull<T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/tests/ui/dyn-star/cell.rs b/tests/ui/dyn-star/cell.rs
new file mode 100644
index 00000000000..f4c7927a39d
--- /dev/null
+++ b/tests/ui/dyn-star/cell.rs
@@ -0,0 +1,34 @@
+// This test with Cell also indirectly exercises UnsafeCell in dyn*.
+//
+//@ run-pass
+
+#![feature(dyn_star)]
+#![allow(incomplete_features)]
+
+use std::cell::Cell;
+
+trait Rw<T> {
+    fn read(&self) -> T;
+    fn write(&self, v: T);
+}
+
+impl<T: Copy> Rw<T> for Cell<T> {
+    fn read(&self) -> T {
+        self.get()
+    }
+    fn write(&self, v: T) {
+        self.set(v)
+    }
+}
+
+fn make_dyn_star() -> dyn* Rw<usize> {
+    Cell::new(42usize) as dyn* Rw<usize>
+}
+
+fn main() {
+    let x = make_dyn_star();
+
+    assert_eq!(x.read(), 42);
+    x.write(24);
+    assert_eq!(x.read(), 24);
+}
diff --git a/tests/ui/dyn-star/error.rs b/tests/ui/dyn-star/error.rs
index 7288596f3fa..1d252d2ce42 100644
--- a/tests/ui/dyn-star/error.rs
+++ b/tests/ui/dyn-star/error.rs
@@ -6,7 +6,7 @@ use std::fmt::Debug;
 trait Foo {}
 
 fn make_dyn_star() {
-    let i = 42;
+    let i = 42usize;
     let dyn_i: dyn* Foo = i; //~ ERROR trait bound `usize: Foo` is not satisfied
 }
 
diff --git a/tests/ui/dyn-star/float-as-dyn-star.stderr b/tests/ui/dyn-star/float-as-dyn-star.stderr
index 9caba512e5f..06071a27afc 100644
--- a/tests/ui/dyn-star/float-as-dyn-star.stderr
+++ b/tests/ui/dyn-star/float-as-dyn-star.stderr
@@ -14,7 +14,9 @@ LL |     f32::from_bits(0x1) as f64
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `f64` needs to be a pointer-like type
    |
    = help: the trait `PointerLike` is not implemented for `f64`
-   = help: the trait `PointerLike` is implemented for `usize`
+   = help: the following other types implement trait `PointerLike`:
+             isize
+             usize
 
 error: aborting due to 1 previous error; 1 warning emitted