diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs deleted file mode 100644 index 35b8120995187..0000000000000 --- a/library/core/src/sync/exclusive.rs +++ /dev/null @@ -1,322 +0,0 @@ -//! Defines [`Exclusive`]. - -use core::clone::TrivialClone; -use core::cmp::Ordering; -use core::fmt; -use core::future::Future; -use core::hash::{Hash, Hasher}; -use core::marker::{StructuralPartialEq, Tuple}; -use core::ops::{Coroutine, CoroutineState}; -use core::pin::Pin; -use core::task::{Context, Poll}; - -/// `Exclusive` provides _mutable_ access, also referred to as _exclusive_ -/// access to the underlying value. However, it only permits _immutable_, or _shared_ -/// access to the underlying value when that value is [`Sync`]. -/// -/// While this may seem not very useful, it allows `Exclusive` to _unconditionally_ -/// implement `Sync`. Indeed, the safety requirements of `Sync` state that for `Exclusive` -/// to be `Sync`, it must be sound to _share_ across threads, that is, it must be sound -/// for `&Exclusive` to cross thread boundaries. By design, a `&Exclusive` for non-`Sync` T -/// has no API whatsoever, making it useless, thus harmless, thus memory safe. -/// -/// Certain constructs like [`Future`]s can only be used with _exclusive_ access, -/// and are often `Send` but not `Sync`, so `Exclusive` can be used as hint to the -/// Rust compiler that something is `Sync` in practice. -/// -/// ## Examples -/// -/// Using a non-`Sync` future prevents the wrapping struct from being `Sync`: -/// -/// ```compile_fail -/// use core::cell::Cell; -/// -/// async fn other() {} -/// fn assert_sync(t: T) {} -/// struct State { -/// future: F -/// } -/// -/// assert_sync(State { -/// future: async { -/// let cell = Cell::new(1); -/// let cell_ref = &cell; -/// other().await; -/// let value = cell_ref.get(); -/// } -/// }); -/// ``` -/// -/// `Exclusive` ensures the struct is `Sync` without stripping the future of its -/// functionality: -/// -/// ``` -/// #![feature(exclusive_wrapper)] -/// use core::cell::Cell; -/// use core::sync::Exclusive; -/// -/// async fn other() {} -/// fn assert_sync(t: T) {} -/// struct State { -/// future: Exclusive -/// } -/// -/// assert_sync(State { -/// future: Exclusive::new(async { -/// let cell = Cell::new(1); -/// let cell_ref = &cell; -/// other().await; -/// let value = cell_ref.get(); -/// }) -/// }); -/// ``` -/// -/// ## Parallels with a mutex -/// -/// In some sense, `Exclusive` can be thought of as a _compile-time_ version of -/// a mutex, as the borrow-checker guarantees that only one `&mut` can exist -/// for any value. This is a parallel with the fact that -/// `&` and `&mut` references together can be thought of as a _compile-time_ -/// version of a read-write lock. -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -#[doc(alias = "SyncWrapper")] -#[doc(alias = "SyncCell")] -#[doc(alias = "Unique")] -// `Exclusive` can't have derived `PartialOrd`, `Clone`, etc. impls as they would -// use `&` access to the inner value, violating the `Sync` impl's safety -// requirements. -#[derive(Default)] -#[repr(transparent)] -pub struct Exclusive { - inner: T, -} - -// See `Exclusive`'s docs for justification. -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -unsafe impl Sync for Exclusive {} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl fmt::Debug for Exclusive { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - f.debug_struct("Exclusive").finish_non_exhaustive() - } -} - -impl Exclusive { - /// Wrap a value in an `Exclusive` - #[unstable(feature = "exclusive_wrapper", issue = "98407")] - #[must_use] - #[inline] - pub const fn new(t: T) -> Self { - Self { inner: t } - } - - /// Unwrap the value contained in the `Exclusive` - #[unstable(feature = "exclusive_wrapper", issue = "98407")] - #[rustc_const_unstable(feature = "exclusive_wrapper", issue = "98407")] - #[must_use] - #[inline] - pub const fn into_inner(self) -> T { - self.inner - } -} - -impl Exclusive { - /// Gets exclusive access to the underlying value. - #[unstable(feature = "exclusive_wrapper", issue = "98407")] - #[must_use] - #[inline] - pub const fn get_mut(&mut self) -> &mut T { - &mut self.inner - } - - /// Gets pinned exclusive access to the underlying value. - /// - /// `Exclusive` is considered to _structurally pin_ the underlying - /// value, which means _unpinned_ `Exclusive`s can produce _unpinned_ - /// access to the underlying value, but _pinned_ `Exclusive`s only - /// produce _pinned_ access to the underlying value. - #[unstable(feature = "exclusive_wrapper", issue = "98407")] - #[must_use] - #[inline] - pub const fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> { - // SAFETY: `Exclusive` can only produce `&mut T` if itself is unpinned - // `Pin::map_unchecked_mut` is not const, so we do this conversion manually - unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } - } - - /// Build a _mutable_ reference to an `Exclusive` from - /// a _mutable_ reference to a `T`. This allows you to skip - /// building an `Exclusive` with [`Exclusive::new`]. - #[unstable(feature = "exclusive_wrapper", issue = "98407")] - #[must_use] - #[inline] - pub const fn from_mut(r: &'_ mut T) -> &'_ mut Exclusive { - // SAFETY: repr is ≥ C, so refs have the same layout; and `Exclusive` properties are `&mut`-agnostic - unsafe { &mut *(r as *mut T as *mut Exclusive) } - } - - /// Build a _pinned mutable_ reference to an `Exclusive` from - /// a _pinned mutable_ reference to a `T`. This allows you to skip - /// building an `Exclusive` with [`Exclusive::new`]. - #[unstable(feature = "exclusive_wrapper", issue = "98407")] - #[must_use] - #[inline] - pub const fn from_pin_mut(r: Pin<&'_ mut T>) -> Pin<&'_ mut Exclusive> { - // SAFETY: `Exclusive` can only produce `&mut T` if itself is unpinned - // `Pin::map_unchecked_mut` is not const, so we do this conversion manually - unsafe { Pin::new_unchecked(Self::from_mut(r.get_unchecked_mut())) } - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -#[rustc_const_unstable(feature = "const_convert", issue = "143773")] -impl const From for Exclusive { - #[inline] - fn from(t: T) -> Self { - Self::new(t) - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl FnOnce for Exclusive -where - F: FnOnce, - Args: Tuple, -{ - type Output = F::Output; - - extern "rust-call" fn call_once(self, args: Args) -> Self::Output { - self.into_inner().call_once(args) - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl FnMut for Exclusive -where - F: FnMut, - Args: Tuple, -{ - extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { - self.get_mut().call_mut(args) - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl Fn for Exclusive -where - F: Sync + Fn, - Args: Tuple, -{ - extern "rust-call" fn call(&self, args: Args) -> Self::Output { - self.as_ref().call(args) - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl Future for Exclusive -where - T: Future + ?Sized, -{ - type Output = T::Output; - - #[inline] - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - self.get_pin_mut().poll(cx) - } -} - -#[unstable(feature = "coroutine_trait", issue = "43122")] // also #98407 -impl Coroutine for Exclusive -where - G: Coroutine + ?Sized, -{ - type Yield = G::Yield; - type Return = G::Return; - - #[inline] - fn resume(self: Pin<&mut Self>, arg: R) -> CoroutineState { - G::resume(self.get_pin_mut(), arg) - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl AsRef for Exclusive -where - T: Sync + ?Sized, -{ - #[inline] - fn as_ref(&self) -> &T { - &self.inner - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl Clone for Exclusive -where - T: Sync + Clone, -{ - #[inline] - fn clone(&self) -> Self { - Self { inner: self.inner.clone() } - } -} - -#[doc(hidden)] -#[unstable(feature = "trivial_clone", issue = "none")] -unsafe impl TrivialClone for Exclusive where T: Sync + TrivialClone {} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl Copy for Exclusive where T: Sync + Copy {} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl PartialEq> for Exclusive -where - T: Sync + PartialEq + ?Sized, - U: Sync + ?Sized, -{ - #[inline] - fn eq(&self, other: &Exclusive) -> bool { - self.inner == other.inner - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl StructuralPartialEq for Exclusive where T: Sync + StructuralPartialEq + ?Sized {} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl Eq for Exclusive where T: Sync + Eq + ?Sized {} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl Hash for Exclusive -where - T: Sync + Hash + ?Sized, -{ - #[inline] - fn hash(&self, state: &mut H) { - Hash::hash(&self.inner, state) - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl PartialOrd> for Exclusive -where - T: Sync + PartialOrd + ?Sized, - U: Sync + ?Sized, -{ - #[inline] - fn partial_cmp(&self, other: &Exclusive) -> Option { - self.inner.partial_cmp(&other.inner) - } -} - -#[unstable(feature = "exclusive_wrapper", issue = "98407")] -impl Ord for Exclusive -where - T: Sync + Ord + ?Sized, -{ - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - self.inner.cmp(&other.inner) - } -} diff --git a/library/core/src/sync/mod.rs b/library/core/src/sync/mod.rs index 4365e4cb250ca..6c2660263a705 100644 --- a/library/core/src/sync/mod.rs +++ b/library/core/src/sync/mod.rs @@ -3,6 +3,6 @@ #![stable(feature = "rust1", since = "1.0.0")] pub mod atomic; -mod exclusive; +mod sync_view; #[unstable(feature = "exclusive_wrapper", issue = "98407")] -pub use exclusive::Exclusive; +pub use sync_view::SyncView; diff --git a/library/core/src/sync/sync_view.rs b/library/core/src/sync/sync_view.rs new file mode 100644 index 0000000000000..46ad41135bfff --- /dev/null +++ b/library/core/src/sync/sync_view.rs @@ -0,0 +1,414 @@ +//! Defines [`SyncView`]. + +use core::clone::TrivialClone; +use core::cmp::Ordering; +use core::fmt; +use core::future::Future; +use core::hash::{Hash, Hasher}; +use core::marker::{StructuralPartialEq, Tuple}; +use core::ops::{Coroutine, CoroutineState}; +use core::pin::Pin; +use core::task::{Context, Poll}; + +/// `SyncView` provides _mutable_ access, also referred to as _exclusive_ +/// access to the underlying value. However, it only permits _immutable_, or _shared_ +/// access to the underlying value when that value is [`Sync`]. +/// +/// While this may seem not very useful, it allows `SyncView` to _unconditionally_ +/// implement `Sync`. Indeed, the safety requirements of `Sync` state that for `SyncView` +/// to be `Sync`, it must be sound to _share_ across threads, that is, it must be sound +/// for `&SyncView` to cross thread boundaries. By design, a `&SyncView` for non-`Sync` +/// `T` has no API whatsoever, making it useless, thus harmless, thus memory safe. +/// +/// Certain constructs like [`Future`]s can only be used with _exclusive_ access, +/// and are often [`Send`] but not `Sync`, so `SyncView` can be used as hint to the +/// Rust compiler that something is `Sync` in practice. +/// +/// ## Examples +/// +/// Using a non-`Sync` future prevents the wrapping struct from being `Sync`: +/// +/// ```compile_fail +/// use core::cell::Cell; +/// +/// async fn other() {} +/// fn assert_sync(t: T) {} +/// struct State { +/// future: F +/// } +/// +/// assert_sync(State { +/// future: async { +/// let cell = Cell::new(1); +/// let cell_ref = &cell; +/// other().await; +/// let value = cell_ref.get(); +/// } +/// }); +/// ``` +/// +/// `SyncView` ensures the struct is `Sync` without stripping the future of its +/// functionality: +/// +/// ``` +/// #![feature(exclusive_wrapper)] +/// use core::cell::Cell; +/// use core::sync::SyncView; +/// +/// async fn other() {} +/// fn assert_sync(t: T) {} +/// struct State { +/// future: SyncView +/// } +/// +/// assert_sync(State { +/// future: SyncView::new(async { +/// let cell = Cell::new(1); +/// let cell_ref = &cell; +/// other().await; +/// let value = cell_ref.get(); +/// }) +/// }); +/// ``` +/// +/// ## Parallels with a mutex +/// +/// In some sense, `SyncView` can be thought of as a _compile-time_ version of +/// a mutex, as the borrow-checker guarantees that only one `&mut` can exist +/// for any value. This is a parallel with the fact that +/// `&` and `&mut` references together can be thought of as a _compile-time_ +/// version of a read-write lock. +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[doc(alias = "SyncWrapper")] +#[doc(alias = "SyncCell")] +#[doc(alias = "Unique")] +#[doc(alias = "Exclusive")] +// `SyncView` can't have derived `PartialOrd`, `Clone`, etc. impls as they would +// use `&` access to the inner value, violating the `Sync` impl's safety +// requirements. +#[repr(transparent)] +pub struct SyncView { + inner: T, +} + +// See `SyncView`'s docs for justification. +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +unsafe impl Sync for SyncView {} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_default", issue = "143894")] +impl const Default for SyncView +where + T: [const] Default, +{ + #[inline] + fn default() -> Self { + Self { inner: Default::default() } + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl fmt::Debug for SyncView { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.debug_struct("SyncView").finish_non_exhaustive() + } +} + +impl SyncView { + /// Wrap a value in an `SyncView` + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[rustc_const_unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + #[inline] + pub const fn new(t: T) -> Self { + Self { inner: t } + } + + /// Unwrap the value contained in the `SyncView` + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[rustc_const_unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + #[inline] + pub const fn into_inner(self) -> T { + self.inner + } +} + +impl SyncView { + /// Gets pinned exclusive access to the underlying value. + /// + /// `SyncView` is considered to _structurally pin_ the underlying + /// value, which means _unpinned_ `SyncView`s can produce _unpinned_ + /// access to the underlying value, but _pinned_ `SyncView`s only + /// produce _pinned_ access to the underlying value. + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[rustc_const_unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + #[inline] + pub const fn as_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> { + // SAFETY: `SyncView` can only produce `&mut T` if itself is unpinned + // `Pin::map_unchecked_mut` is not const, so we do this conversion manually + unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } + } + + /// Build a _mutable_ reference to an `SyncView` from + /// a _mutable_ reference to a `T`. This allows you to skip + /// building an `SyncView` with [`SyncView::new`]. + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[rustc_const_unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + #[inline] + pub const fn from_mut(r: &'_ mut T) -> &'_ mut SyncView { + // SAFETY: repr is ≥ C, so refs have the same layout; and `SyncView` properties are `&mut`-agnostic + unsafe { &mut *(r as *mut T as *mut SyncView) } + } + + /// Build a _pinned mutable_ reference to an `SyncView` from + /// a _pinned mutable_ reference to a `T`. This allows you to skip + /// building an `SyncView` with [`SyncView::new`]. + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[rustc_const_unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + #[inline] + pub const fn from_pin_mut(r: Pin<&'_ mut T>) -> Pin<&'_ mut SyncView> { + // SAFETY: `SyncView` can only produce `&mut T` if itself is unpinned + // `Pin::map_unchecked_mut` is not const, so we do this conversion manually + unsafe { Pin::new_unchecked(Self::from_mut(r.get_unchecked_mut())) } + } +} + +impl SyncView { + /// Gets pinned shared access to the underlying value. + /// + /// `SyncView` is considered to _structurally pin_ the underlying + /// value, which means _unpinned_ `SyncView`s can produce _unpinned_ + /// access to the underlying value, but _pinned_ `SyncView`s only + /// produce _pinned_ access to the underlying value. + #[unstable(feature = "exclusive_wrapper", issue = "98407")] + #[rustc_const_unstable(feature = "exclusive_wrapper", issue = "98407")] + #[must_use] + #[inline] + pub const fn as_pin(self: Pin<&Self>) -> Pin<&T> { + // SAFETY: `SyncView` can only produce `&T` if itself is unpinned + // `Pin::map_unchecked` is not const, so we do this conversion manually + unsafe { Pin::new_unchecked(&self.get_ref().inner) } + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_convert", issue = "143773")] +impl const From for SyncView { + #[inline] + fn from(t: T) -> Self { + Self::new(t) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")] +impl const FnOnce for SyncView +where + F: [const] FnOnce, + Args: Tuple, +{ + type Output = F::Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output { + self.into_inner().call_once(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")] +impl const FnMut for SyncView +where + F: [const] FnMut, + Args: Tuple, +{ + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output { + self.as_mut().call_mut(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")] +impl const Fn for SyncView +where + F: Sync + [const] Fn, + Args: Tuple, +{ + extern "rust-call" fn call(&self, args: Args) -> Self::Output { + self.as_ref().call(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl AsyncFnOnce for SyncView +where + F: AsyncFnOnce, + Args: Tuple, +{ + type CallOnceFuture = F::CallOnceFuture; + + type Output = F::Output; + + extern "rust-call" fn async_call_once(self, args: Args) -> Self::CallOnceFuture { + self.into_inner().async_call_once(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl AsyncFnMut for SyncView +where + F: AsyncFnMut, + Args: Tuple, +{ + type CallRefFuture<'a> + = F::CallRefFuture<'a> + where + F: 'a; + + extern "rust-call" fn async_call_mut(&mut self, args: Args) -> Self::CallRefFuture<'_> { + self.as_mut().async_call_mut(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl AsyncFn for SyncView +where + F: Sync + AsyncFn, + Args: Tuple, +{ + extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> { + self.as_ref().async_call(args) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl Future for SyncView +where + T: Future + ?Sized, +{ + type Output = T::Output; + + #[inline] + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.as_pin_mut().poll(cx) + } +} + +#[unstable(feature = "coroutine_trait", issue = "43122")] // also #98407 +impl Coroutine for SyncView +where + G: Coroutine + ?Sized, +{ + type Yield = G::Yield; + type Return = G::Return; + + #[inline] + fn resume(self: Pin<&mut Self>, arg: R) -> CoroutineState { + G::resume(self.as_pin_mut(), arg) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_convert", issue = "143773")] +impl const AsRef for SyncView +where + T: Sync + ?Sized, +{ + /// Gets shared access to the underlying value. + #[inline] + fn as_ref(&self) -> &T { + &self.inner + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_convert", issue = "143773")] +impl const AsMut for SyncView +where + T: ?Sized, +{ + /// Gets exclusive access to the underlying value. + #[inline] + fn as_mut(&mut self) -> &mut T { + &mut self.inner + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +impl const Clone for SyncView +where + T: Sync + [const] Clone, +{ + #[inline] + fn clone(&self) -> Self { + Self { inner: self.inner.clone() } + } +} + +#[doc(hidden)] +#[unstable(feature = "trivial_clone", issue = "none")] +#[rustc_const_unstable(feature = "const_clone", issue = "142757")] +unsafe impl const TrivialClone for SyncView where T: Sync + [const] TrivialClone {} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl Copy for SyncView where T: Sync + Copy {} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const PartialEq> for SyncView +where + T: Sync + [const] PartialEq + ?Sized, + U: Sync + ?Sized, +{ + #[inline] + fn eq(&self, other: &SyncView) -> bool { + self.inner == other.inner + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl StructuralPartialEq for SyncView where T: Sync + StructuralPartialEq + ?Sized {} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const Eq for SyncView where T: Sync + [const] Eq + ?Sized {} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +impl Hash for SyncView +where + T: Sync + Hash + ?Sized, +{ + #[inline] + fn hash(&self, state: &mut H) { + Hash::hash(&self.inner, state) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const PartialOrd> for SyncView +where + T: Sync + [const] PartialOrd + ?Sized, + U: Sync + ?Sized, +{ + #[inline] + fn partial_cmp(&self, other: &SyncView) -> Option { + self.inner.partial_cmp(&other.inner) + } +} + +#[unstable(feature = "exclusive_wrapper", issue = "98407")] +#[rustc_const_unstable(feature = "const_cmp", issue = "143800")] +impl const Ord for SyncView +where + T: Sync + [const] Ord + ?Sized, +{ + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + self.inner.cmp(&other.inner) + } +} diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs index 5da50480c7232..439b5b09a5ac0 100644 --- a/library/std/src/sync/mod.rs +++ b/library/std/src/sync/mod.rs @@ -172,7 +172,7 @@ // These come from `core` & `alloc` and only in one flavor: no poisoning. #[unstable(feature = "exclusive_wrapper", issue = "98407")] -pub use core::sync::Exclusive; +pub use core::sync::SyncView; #[stable(feature = "rust1", since = "1.0.0")] pub use core::sync::atomic; diff --git a/tests/ui/explicit-tail-calls/callee_is_weird.rs b/tests/ui/explicit-tail-calls/callee_is_weird.rs index b3ca878c232c2..9e2b1fb8d4b55 100644 --- a/tests/ui/explicit-tail-calls/callee_is_weird.rs +++ b/tests/ui/explicit-tail-calls/callee_is_weird.rs @@ -4,11 +4,11 @@ fn f() {} fn g() { - become std::sync::Exclusive::new(f)() //~ error: tail calls can only be performed with function definitions or pointers + become std::sync::SyncView::new(f)() //~ error: tail calls can only be performed with function definitions or pointers } fn h() { - become (&mut &std::sync::Exclusive::new(f))() //~ error: tail calls can only be performed with function definitions or pointers + become (&mut &std::sync::SyncView::new(f))() //~ error: tail calls can only be performed with function definitions or pointers } fn i() { diff --git a/tests/ui/explicit-tail-calls/callee_is_weird.stderr b/tests/ui/explicit-tail-calls/callee_is_weird.stderr index 9a5da28b559e3..f31c2f08c6c62 100644 --- a/tests/ui/explicit-tail-calls/callee_is_weird.stderr +++ b/tests/ui/explicit-tail-calls/callee_is_weird.stderr @@ -1,18 +1,18 @@ error: tail calls can only be performed with function definitions or pointers --> $DIR/callee_is_weird.rs:7:12 | -LL | become std::sync::Exclusive::new(f)() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | become std::sync::SyncView::new(f)() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: callee has type `Exclusive` + = note: callee has type `SyncView` error: tail calls can only be performed with function definitions or pointers --> $DIR/callee_is_weird.rs:11:12 | -LL | become (&mut &std::sync::Exclusive::new(f))() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | become (&mut &std::sync::SyncView::new(f))() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: callee has type `&Exclusive` + = note: callee has type `&SyncView` error: tail calls can only be performed with function definitions or pointers --> $DIR/callee_is_weird.rs:22:12 diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 2d925165d583a..52b63ae8177ea 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -387,7 +387,7 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani where A: std::marker::Tuple, F: Fn, F: ?Sized; - impl Fn for Box where Args: std::marker::Tuple, F: Fn, A: Allocator, F: ?Sized; - - impl Fn for Exclusive + - impl Fn for SyncView where F: Sync, F: Fn, Args: std::marker::Tuple; error: unconstrained opaque type diff --git a/tests/ui/traits/next-solver/well-formed-in-relate.stderr b/tests/ui/traits/next-solver/well-formed-in-relate.stderr index 264ab9bebbb92..dbe8a656812a5 100644 --- a/tests/ui/traits/next-solver/well-formed-in-relate.stderr +++ b/tests/ui/traits/next-solver/well-formed-in-relate.stderr @@ -12,7 +12,7 @@ LL | x = unconstrained_map(); where A: std::marker::Tuple, F: Fn, F: ?Sized; - impl Fn for Box where Args: std::marker::Tuple, F: Fn, A: Allocator, F: ?Sized; - - impl Fn for Exclusive + - impl Fn for SyncView where F: Sync, F: Fn, Args: std::marker::Tuple; note: required by a bound in `unconstrained_map` --> $DIR/well-formed-in-relate.rs:21:25