From a2d1cb2c22016ae003ab51d9654746cc4fc5200a Mon Sep 17 00:00:00 2001 From: dimi Date: Tue, 24 May 2022 23:56:19 +0200 Subject: [PATCH] impl DispatchFromDyn for Cell and UnsafeCell --- library/core/src/cell.rs | 33 ++++++++++++++++++- ...itrary_self_types_pointers_and_wrappers.rs | 22 +++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 129213fde74..7f109491350 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -196,7 +196,7 @@ use crate::fmt::{self, Debug, Display}; use crate::marker::{PhantomData, Unsize}; use crate::mem; -use crate::ops::{CoerceUnsized, Deref, DerefMut}; +use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn}; use crate::ptr::{self, NonNull}; mod lazy; @@ -571,6 +571,16 @@ pub fn take(&self) -> T { #[unstable(feature = "coerce_unsized", issue = "18598")] impl, U> CoerceUnsized> for Cell {} +// Allow types that wrap `Cell` to also implement `DispatchFromDyn` +// and become object safe method receivers. +// Note that currently `Cell` itself cannot be a method receiver +// because it does not implement Deref. +// In other words: +// `self: Cell<&Self>` won't work +// `self: CellWrapper` becomes possible +#[unstable(feature = "dispatch_from_dyn", issue = "none")] +impl, U> DispatchFromDyn> for Cell {} + impl Cell<[T]> { /// Returns a `&[Cell]` from a `&Cell<[T]>` /// @@ -2078,6 +2088,16 @@ fn from(t: T) -> UnsafeCell { #[unstable(feature = "coerce_unsized", issue = "18598")] impl, U> CoerceUnsized> for UnsafeCell {} +// Allow types that wrap `UnsafeCell` to also implement `DispatchFromDyn` +// and become object safe method receivers. +// Note that currently `UnsafeCell` itself cannot be a method receiver +// because it does not implement Deref. +// In other words: +// `self: UnsafeCell<&Self>` won't work +// `self: UnsafeCellWrapper` becomes possible +#[unstable(feature = "dispatch_from_dyn", issue = "none")] +impl, U> DispatchFromDyn> for UnsafeCell {} + /// [`UnsafeCell`], but [`Sync`]. /// /// This is just an `UnsafeCell`, except it implements `Sync` @@ -2169,6 +2189,17 @@ fn from(t: T) -> SyncUnsafeCell { //#[unstable(feature = "sync_unsafe_cell", issue = "95439")] impl, U> CoerceUnsized> for SyncUnsafeCell {} +// Allow types that wrap `SyncUnsafeCell` to also implement `DispatchFromDyn` +// and become object safe method receivers. +// Note that currently `SyncUnsafeCell` itself cannot be a method receiver +// because it does not implement Deref. +// In other words: +// `self: SyncUnsafeCell<&Self>` won't work +// `self: SyncUnsafeCellWrapper` becomes possible +#[unstable(feature = "dispatch_from_dyn", issue = "none")] +//#[unstable(feature = "sync_unsafe_cell", issue = "95439")] +impl, U> DispatchFromDyn> for SyncUnsafeCell {} + #[allow(unused)] fn assert_coerce_unsized( a: UnsafeCell<&i32>, diff --git a/tests/ui/self/arbitrary_self_types_pointers_and_wrappers.rs b/tests/ui/self/arbitrary_self_types_pointers_and_wrappers.rs index 65fec3becac..91aacedfc57 100644 --- a/tests/ui/self/arbitrary_self_types_pointers_and_wrappers.rs +++ b/tests/ui/self/arbitrary_self_types_pointers_and_wrappers.rs @@ -3,6 +3,7 @@ #![feature(rustc_attrs)] use std::{ + cell::Cell, ops::{Deref, CoerceUnsized, DispatchFromDyn}, marker::Unsize, }; @@ -20,6 +21,20 @@ fn deref(&self) -> &T { impl + ?Sized, U: ?Sized> CoerceUnsized> for Ptr {} impl + ?Sized, U: ?Sized> DispatchFromDyn> for Ptr {} + +struct CellPtr<'a, T: ?Sized>(Cell<&'a T>); + +impl<'a, T: ?Sized> Deref for CellPtr<'a, T> { + type Target = T; + + fn deref(&self) -> &T { + self.0.get() + } +} + +impl<'a, T: Unsize + ?Sized, U: ?Sized> CoerceUnsized> for CellPtr<'a, T> {} +impl<'a, T: Unsize + ?Sized, U: ?Sized> DispatchFromDyn> for CellPtr<'a, T> {} + struct Wrapper(T); impl Deref for Wrapper { @@ -42,6 +57,7 @@ trait Trait { fn ptr_wrapper(self: Ptr>) -> i32; fn wrapper_ptr(self: Wrapper>) -> i32; fn wrapper_ptr_wrapper(self: Wrapper>>) -> i32; + fn cell(self: CellPtr) -> i32; } impl Trait for i32 { @@ -54,6 +70,9 @@ fn wrapper_ptr(self: Wrapper>) -> i32 { fn wrapper_ptr_wrapper(self: Wrapper>>) -> i32 { ***self } + fn cell(self: CellPtr) -> i32 { + *self + } } fn main() { @@ -65,4 +84,7 @@ fn main() { let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper>>; assert_eq!(wpw.wrapper_ptr_wrapper(), 7); + + let c = CellPtr(Cell::new(&8)) as CellPtr; + assert_eq!(c.cell(), 8); }