From 5c04151c6cea29398b786b3fa781ec2f8f5ed1da Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sat, 21 Dec 2024 17:13:52 -0800 Subject: [PATCH] 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. --- library/core/src/cell.rs | 11 ++++++- library/core/src/marker.rs | 1 + library/core/src/ptr/non_null.rs | 4 +++ tests/ui/dyn-star/cell.rs | 34 ++++++++++++++++++++++ tests/ui/dyn-star/error.rs | 2 +- tests/ui/dyn-star/float-as-dyn-star.stderr | 4 ++- 6 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 tests/ui/dyn-star/cell.rs diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index cfa4c1fb56479..306d565a77e66 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, U> CoerceUnsized> for Cell {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl, U> DispatchFromDyn> for Cell {} +#[unstable(feature = "pointer_like_trait", issue = "none")] +impl PointerLike for Cell {} + impl Cell<[T]> { /// Returns a `&[Cell]` from a `&Cell<[T]>` /// @@ -2258,6 +2261,9 @@ impl, U> CoerceUnsized> for UnsafeCell {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl, U> DispatchFromDyn> for UnsafeCell {} +#[unstable(feature = "pointer_like_trait", issue = "none")] +impl PointerLike for UnsafeCell {} + /// [`UnsafeCell`], but [`Sync`]. /// /// This is just an `UnsafeCell`, except it implements `Sync` @@ -2364,6 +2370,9 @@ impl, U> CoerceUnsized> for SyncUnsafeCell //#[unstable(feature = "sync_unsafe_cell", issue = "95439")] impl, U> DispatchFromDyn> for SyncUnsafeCell {} +#[unstable(feature = "pointer_like_trait", issue = "none")] +impl PointerLike for SyncUnsafeCell {} + #[allow(unused)] fn assert_coerce_unsized( a: UnsafeCell<&i32>, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 3d79706f8ecf9..b8613ce44c56e 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 6b601405e1c2a..97b0020d53c3e 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1548,6 +1548,10 @@ impl DispatchFromDyn> for NonNull where T: U #[stable(feature = "pin", since = "1.33.0")] unsafe impl PinCoerceUnsized for NonNull {} +#[unstable(feature = "pointer_like_trait", issue = "none")] +#[cfg(not(bootstrap))] +impl core::marker::PointerLike for NonNull {} + #[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Debug for NonNull { 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 0000000000000..f4c7927a39dc9 --- /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 { + fn read(&self) -> T; + fn write(&self, v: T); +} + +impl Rw for Cell { + fn read(&self) -> T { + self.get() + } + fn write(&self, v: T) { + self.set(v) + } +} + +fn make_dyn_star() -> dyn* Rw { + Cell::new(42usize) as dyn* Rw +} + +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 7288596f3fa8a..1d252d2ce42b2 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 9caba512e5f43..06071a27afc61 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