diff options
| author | Kevin Reid <kpreid@switchb.org> | 2024-12-21 17:13:52 -0800 |
|---|---|---|
| committer | Kevin Reid <kpreid@switchb.org> | 2024-12-22 11:18:56 -0800 |
| commit | 5c04151c6cea29398b786b3fa781ec2f8f5ed1da (patch) | |
| tree | a063fc7a59a4f7045fc8dcfcb9f38c942259237b | |
| parent | 13170cd787cb733ed24842ee825bcbd98dc01476 (diff) | |
| download | rust-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.rs | 11 | ||||
| -rw-r--r-- | library/core/src/marker.rs | 1 | ||||
| -rw-r--r-- | library/core/src/ptr/non_null.rs | 4 | ||||
| -rw-r--r-- | tests/ui/dyn-star/cell.rs | 34 | ||||
| -rw-r--r-- | tests/ui/dyn-star/error.rs | 2 | ||||
| -rw-r--r-- | tests/ui/dyn-star/float-as-dyn-star.stderr | 4 |
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 |
