#![no_std]
#![feature(generic_associated_types)]
#![allow(unsafe_code)]
#![deny(missing_docs)]
extern crate alloc;
use alloc::sync::Arc;
use core::cmp;
use core::fmt;
use core::fmt::{Debug, Display};
use core::ops::{Deref, DerefMut};
use core::sync::atomic;
use core::sync::atomic::AtomicUsize;
use core::{cell::UnsafeCell, convert::Infallible};
use hv_guarded_borrow::{
NonBlockingGuardedBorrow, NonBlockingGuardedBorrowMut, NonBlockingGuardedMutBorrowMut,
};
#[cfg(feature = "track-leases")]
use hv_lease_tracker::{Lease, LeaseTracker};
pub struct ArcCell<T: ?Sized> {
inner: Arc<AtomicRefCell<T>>,
}
impl<T> ArcCell<T> {
#[inline]
pub fn new(value: T) -> Self {
Self {
inner: Arc::new(AtomicRefCell::new(value)),
}
}
}
impl<T: ?Sized> ArcCell<T> {
#[inline]
pub fn borrow(&self) -> ArcRef<T> {
match AtomicBorrowRef::try_new(&self.inner.borrows) {
Ok(borrow) => ArcRef {
value: unsafe { &*(*self.inner).value.get() },
guard: ArcRefGuard {
borrow,
cell: self.inner.clone(),
},
#[cfg(feature = "track-leases")]
lease: self.inner.lease_tracker.lease_at_caller(Some("immutable")),
},
Err(s) => panic!("{}", s),
}
}
#[inline]
pub fn try_borrow(&self) -> Result<ArcRef<T>, BorrowError> {
match AtomicBorrowRef::try_new(&self.inner.borrows) {
Ok(borrow) => Ok(ArcRef {
value: unsafe { &*self.inner.value.get() },
guard: ArcRefGuard {
borrow,
cell: self.inner.clone(),
},
#[cfg(feature = "track-leases")]
lease: self.inner.lease_tracker.lease_at_caller(Some("immutable")),
}),
Err(_) => Err(BorrowError { _private: () }),
}
}
#[inline]
pub fn borrow_mut(&self) -> ArcRefMut<T> {
match AtomicBorrowRefMut::try_new(&self.inner.borrows) {
Ok(borrow) => ArcRefMut {
value: unsafe { &mut *self.inner.value.get() },
guard: ArcRefMutGuard {
cell: self.inner.clone(),
borrow,
},
#[cfg(feature = "track-leases")]
lease: self.inner.lease_tracker.lease_at_caller(Some("mutable")),
},
Err(s) => panic!("{}", s),
}
}
#[inline]
pub fn try_borrow_mut(&self) -> Result<ArcRefMut<T>, BorrowMutError> {
match AtomicBorrowRefMut::try_new(&self.inner.borrows) {
Ok(borrow) => Ok(ArcRefMut {
value: unsafe { &mut *self.inner.value.get() },
guard: ArcRefMutGuard {
cell: self.inner.clone(),
borrow,
},
#[cfg(feature = "track-leases")]
lease: self.inner.lease_tracker.lease_at_caller(Some("mutable")),
}),
Err(_) => Err(BorrowMutError { _private: () }),
}
}
#[inline]
pub fn as_inner(&self) -> &Arc<AtomicRefCell<T>> {
&self.inner
}
#[inline]
pub fn into_inner(self) -> Arc<AtomicRefCell<T>> {
self.inner
}
#[inline]
pub fn from_inner(inner: Arc<AtomicRefCell<T>>) -> Self {
Self { inner }
}
}
pub struct AtomicRefCell<T: ?Sized> {
#[cfg(feature = "track-leases")]
lease_tracker: LeaseTracker,
borrows: AtomicUsize,
value: UnsafeCell<T>,
}
pub struct BorrowError {
_private: (),
}
impl Debug for BorrowError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BorrowError").finish()
}
}
impl Display for BorrowError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt("already mutably borrowed", f)
}
}
pub struct BorrowMutError {
_private: (),
}
impl Debug for BorrowMutError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BorrowMutError").finish()
}
}
impl Display for BorrowMutError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt("already borrowed", f)
}
}
impl<T> AtomicRefCell<T> {
#[inline]
pub fn new(value: T) -> AtomicRefCell<T> {
AtomicRefCell {
#[cfg(feature = "track-leases")]
lease_tracker: LeaseTracker::new(),
borrows: AtomicUsize::new(0),
value: UnsafeCell::new(value),
}
}
#[inline]
pub fn into_inner(self) -> T {
debug_assert!(self.borrows.load(atomic::Ordering::Acquire) == 0);
self.value.into_inner()
}
}
impl<T: ?Sized> AtomicRefCell<T> {
#[inline]
#[track_caller]
pub fn borrow(&self) -> AtomicRef<T> {
match AtomicBorrowRef::try_new(&self.borrows) {
Ok(borrow) => AtomicRef {
value: unsafe { &*self.value.get() },
guard: AtomicRefGuard {
count: &self.borrows,
borrow,
},
#[cfg(feature = "track-leases")]
lease: self.lease_tracker.lease_at_caller(Some("immutable")),
},
Err(s) => panic!("{}", s),
}
}
#[inline]
#[track_caller]
pub fn try_borrow(&self) -> Result<AtomicRef<T>, BorrowError> {
match AtomicBorrowRef::try_new(&self.borrows) {
Ok(borrow) => Ok(AtomicRef {
value: unsafe { &*self.value.get() },
guard: AtomicRefGuard {
count: &self.borrows,
borrow,
},
#[cfg(feature = "track-leases")]
lease: self.lease_tracker.lease_at_caller(Some("immutable")),
}),
Err(_) => Err(BorrowError { _private: () }),
}
}
#[inline]
#[track_caller]
pub fn borrow_mut(&self) -> AtomicRefMut<T> {
match AtomicBorrowRefMut::try_new(&self.borrows) {
Ok(borrow) => AtomicRefMut {
value: unsafe { &mut *self.value.get() },
guard: AtomicRefMutGuard {
count: &self.borrows,
borrow,
},
#[cfg(feature = "track-leases")]
lease: self.lease_tracker.lease_at_caller(Some("mutable")),
},
Err(s) => panic!("{}", s),
}
}
#[inline]
#[track_caller]
pub fn try_borrow_mut(&self) -> Result<AtomicRefMut<T>, BorrowMutError> {
match AtomicBorrowRefMut::try_new(&self.borrows) {
Ok(borrow) => Ok(AtomicRefMut {
value: unsafe { &mut *self.value.get() },
guard: AtomicRefMutGuard {
count: &self.borrows,
borrow,
},
#[cfg(feature = "track-leases")]
lease: self.lease_tracker.lease_at_caller(Some("mutable")),
}),
Err(_) => Err(BorrowMutError { _private: () }),
}
}
#[inline]
pub fn as_ptr(&self) -> *mut T {
self.value.get()
}
#[inline]
pub fn get_mut(&mut self) -> &mut T {
debug_assert!(self.borrows.load(atomic::Ordering::Acquire) == 0);
unsafe { &mut *self.value.get() }
}
}
const HIGH_BIT: usize = !(::core::usize::MAX >> 1);
const MAX_FAILED_BORROWS: usize = HIGH_BIT + (HIGH_BIT >> 1);
struct AtomicBorrowRef;
impl AtomicBorrowRef {
#[inline]
fn try_new(borrow: &AtomicUsize) -> Result<Self, &'static str> {
let new = borrow.fetch_add(1, atomic::Ordering::Acquire) + 1;
if new & HIGH_BIT != 0 {
Self::check_overflow(borrow, new);
Err("already mutably borrowed")
} else {
Ok(AtomicBorrowRef)
}
}
#[cold]
#[inline(never)]
fn check_overflow(borrow: &AtomicUsize, new: usize) {
if new == HIGH_BIT {
borrow.fetch_sub(1, atomic::Ordering::Release);
panic!("too many immutable borrows");
} else if new >= MAX_FAILED_BORROWS {
struct ForceAbort;
impl Drop for ForceAbort {
fn drop(&mut self) {
panic!("Aborting to avoid unsound state of AtomicRefCell");
}
}
let _abort = ForceAbort;
panic!("Too many failed borrows");
}
}
#[inline]
fn release(&self, borrow: &AtomicUsize) {
let old = borrow.fetch_sub(1, atomic::Ordering::Release);
debug_assert!(old & HIGH_BIT == 0);
}
}
struct AtomicBorrowRefMut;
impl AtomicBorrowRefMut {
#[inline]
fn try_new(borrow: &AtomicUsize) -> Result<Self, &'static str> {
let old = match borrow.compare_exchange(
0,
HIGH_BIT,
atomic::Ordering::Acquire,
atomic::Ordering::Relaxed,
) {
Ok(x) => x,
Err(x) => x,
};
if old == 0 {
Ok(AtomicBorrowRefMut)
} else if old & HIGH_BIT == 0 {
Err("already immutably borrowed")
} else {
Err("already mutably borrowed")
}
}
#[inline]
fn release(&self, borrow: &AtomicUsize) {
borrow.store(0, atomic::Ordering::Release);
}
}
unsafe impl<T: ?Sized + Send> Send for AtomicRefCell<T> {}
unsafe impl<T: ?Sized + Send + Sync> Sync for AtomicRefCell<T> {}
impl<T: Clone> Clone for AtomicRefCell<T> {
#[inline]
fn clone(&self) -> AtomicRefCell<T> {
AtomicRefCell::new((*self.borrow()).clone())
}
}
impl<T: Default> Default for AtomicRefCell<T> {
#[inline]
fn default() -> AtomicRefCell<T> {
AtomicRefCell::new(Default::default())
}
}
impl<T: ?Sized + PartialEq> PartialEq for AtomicRefCell<T> {
#[inline]
fn eq(&self, other: &AtomicRefCell<T>) -> bool {
*self.borrow() == *other.borrow()
}
}
impl<T: ?Sized + Eq> Eq for AtomicRefCell<T> {}
impl<T: ?Sized + PartialOrd> PartialOrd for AtomicRefCell<T> {
#[inline]
fn partial_cmp(&self, other: &AtomicRefCell<T>) -> Option<cmp::Ordering> {
self.borrow().partial_cmp(&*other.borrow())
}
}
impl<T: ?Sized + Ord> Ord for AtomicRefCell<T> {
#[inline]
fn cmp(&self, other: &AtomicRefCell<T>) -> cmp::Ordering {
self.borrow().cmp(&*other.borrow())
}
}
impl<T> From<T> for AtomicRefCell<T> {
fn from(t: T) -> AtomicRefCell<T> {
AtomicRefCell::new(t)
}
}
impl<T: ?Sized> Clone for ArcCell<T> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<T: Default> Default for ArcCell<T> {
#[inline]
fn default() -> ArcCell<T> {
ArcCell::new(Default::default())
}
}
impl<T: ?Sized + PartialEq> PartialEq for ArcCell<T> {
#[inline]
fn eq(&self, other: &ArcCell<T>) -> bool {
*self.borrow() == *other.borrow()
}
}
impl<T: ?Sized + Eq> Eq for ArcCell<T> {}
impl<T: ?Sized + PartialOrd> PartialOrd for ArcCell<T> {
#[inline]
fn partial_cmp(&self, other: &ArcCell<T>) -> Option<cmp::Ordering> {
self.borrow().partial_cmp(&*other.borrow())
}
}
impl<T: ?Sized + Ord> Ord for ArcCell<T> {
#[inline]
fn cmp(&self, other: &ArcCell<T>) -> cmp::Ordering {
self.borrow().cmp(&*other.borrow())
}
}
impl<T> From<T> for ArcCell<T> {
fn from(t: T) -> ArcCell<T> {
ArcCell::new(t)
}
}
struct AtomicRefGuard<'b> {
count: &'b AtomicUsize,
borrow: AtomicBorrowRef,
}
impl<'b> Drop for AtomicRefGuard<'b> {
fn drop(&mut self) {
self.borrow.release(self.count);
}
}
impl<'b> Clone for AtomicRefGuard<'b> {
#[inline]
#[track_caller]
fn clone(&self) -> Self {
Self {
count: self.count,
borrow: AtomicBorrowRef::try_new(self.count).unwrap(),
}
}
}
pub struct AtomicRef<'b, T: ?Sized + 'b> {
value: &'b T,
guard: AtomicRefGuard<'b>,
#[cfg(feature = "track-leases")]
lease: Lease,
}
impl<'b, T: ?Sized> Deref for AtomicRef<'b, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.value
}
}
impl<'b, T: ?Sized> Clone for AtomicRef<'b, T> {
#[inline]
#[track_caller]
fn clone(&self) -> AtomicRef<'b, T> {
AtomicRef {
value: self.value,
guard: self.guard.clone(),
#[cfg(feature = "track-leases")]
lease: self.lease.tracker().lease_at_caller(Some("immutable")),
}
}
}
impl<'b, T: ?Sized> AtomicRef<'b, T> {
#[inline]
pub fn map<U: ?Sized, F>(orig: AtomicRef<'b, T>, f: F) -> AtomicRef<'b, U>
where
F: FnOnce(&T) -> &U,
{
AtomicRef {
value: f(orig.value),
guard: orig.guard,
#[cfg(feature = "track-leases")]
lease: orig.lease,
}
}
#[inline]
pub fn filter_map<U: ?Sized, F>(orig: AtomicRef<'b, T>, f: F) -> Option<AtomicRef<'b, U>>
where
F: FnOnce(&T) -> Option<&U>,
{
Some(AtomicRef {
value: f(orig.value)?,
guard: orig.guard,
#[cfg(feature = "track-leases")]
lease: orig.lease,
})
}
}
struct AtomicRefMutGuard<'b> {
count: &'b AtomicUsize,
borrow: AtomicBorrowRefMut,
}
impl<'b> Drop for AtomicRefMutGuard<'b> {
fn drop(&mut self) {
self.borrow.release(self.count);
}
}
pub struct AtomicRefMut<'b, T: ?Sized + 'b> {
value: &'b mut T,
guard: AtomicRefMutGuard<'b>,
#[cfg(feature = "track-leases")]
lease: Lease,
}
impl<'b, T: ?Sized> AtomicRefMut<'b, T> {
#[inline]
pub fn map<U: ?Sized, F>(orig: AtomicRefMut<'b, T>, f: F) -> AtomicRefMut<'b, U>
where
F: FnOnce(&mut T) -> &mut U,
{
AtomicRefMut {
value: f(orig.value),
guard: orig.guard,
#[cfg(feature = "track-leases")]
lease: orig.lease,
}
}
#[inline]
pub fn filter_map<U: ?Sized, F>(orig: AtomicRefMut<'b, T>, f: F) -> Option<AtomicRefMut<'b, U>>
where
F: FnOnce(&mut T) -> Option<&mut U>,
{
Some(AtomicRefMut {
value: f(orig.value)?,
guard: orig.guard,
#[cfg(feature = "track-leases")]
lease: orig.lease,
})
}
}
impl<'b, T: ?Sized> Deref for AtomicRefMut<'b, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.value
}
}
impl<'b, T: ?Sized> DerefMut for AtomicRefMut<'b, T> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
self.value
}
}
impl<'b, T: ?Sized + Debug + 'b> Debug for AtomicRef<'b, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
impl<'b, T: ?Sized + Debug + 'b> Debug for AtomicRefMut<'b, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
struct ArcRefGuard<C: ?Sized> {
cell: Arc<AtomicRefCell<C>>,
borrow: AtomicBorrowRef,
}
impl<C: ?Sized> Drop for ArcRefGuard<C> {
fn drop(&mut self) {
self.borrow.release(&self.cell.borrows);
}
}
pub struct ArcRef<T: ?Sized, C: ?Sized = T> {
value: *const T,
guard: ArcRefGuard<C>,
#[cfg(feature = "track-leases")]
lease: Lease,
}
unsafe impl<T: Send + Sync, C: ?Sized + Send + Sync> Send for ArcRef<T, C> {}
unsafe impl<T: Send + Sync, C: ?Sized> Sync for ArcRef<T, C> {}
impl<T: ?Sized, C: ?Sized> Deref for ArcRef<T, C> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
unsafe { &*self.value }
}
}
impl<T: ?Sized, C: ?Sized> Clone for ArcRef<T, C> {
fn clone(&self) -> Self {
ArcRef {
value: self.value,
guard: ArcRefGuard {
cell: self.guard.cell.clone(),
borrow: AtomicBorrowRef::try_new(&self.guard.cell.borrows).unwrap(),
},
#[cfg(feature = "track-leases")]
lease: self.lease.tracker().lease_at_caller(Some("immutable")),
}
}
}
impl<T: ?Sized, C: ?Sized> ArcRef<T, C> {
#[inline]
pub fn map<U: ?Sized, F>(orig: ArcRef<T, C>, f: F) -> ArcRef<U, C>
where
F: FnOnce(&T) -> &U,
{
ArcRef {
value: f(unsafe { &*orig.value }),
guard: orig.guard,
#[cfg(feature = "track-leases")]
lease: orig.lease,
}
}
#[inline]
pub fn filter_map<U: ?Sized, F>(orig: ArcRef<T, C>, f: F) -> Option<ArcRef<U, C>>
where
F: FnOnce(&T) -> Option<&U>,
{
Some(ArcRef {
value: f(unsafe { &*orig.value })?,
guard: orig.guard,
#[cfg(feature = "track-leases")]
lease: orig.lease,
})
}
}
struct ArcRefMutGuard<C: ?Sized> {
cell: Arc<AtomicRefCell<C>>,
borrow: AtomicBorrowRefMut,
}
impl<C: ?Sized> Drop for ArcRefMutGuard<C> {
fn drop(&mut self) {
self.borrow.release(&self.cell.borrows);
}
}
pub struct ArcRefMut<T: ?Sized, C: ?Sized = T> {
value: *mut T,
guard: ArcRefMutGuard<C>,
#[cfg(feature = "track-leases")]
lease: Lease,
}
unsafe impl<T: Send + Sync, C: ?Sized + Send + Sync> Send for ArcRefMut<T, C> {}
unsafe impl<T: Send + Sync, C: ?Sized> Sync for ArcRefMut<T, C> {}
impl<T: ?Sized, C: ?Sized> ArcRefMut<T, C> {
#[inline]
pub fn map<U: ?Sized, F>(orig: ArcRefMut<T, C>, f: F) -> ArcRefMut<U, C>
where
F: FnOnce(&mut T) -> &mut U,
{
ArcRefMut {
value: f(unsafe { &mut *orig.value }),
guard: orig.guard,
#[cfg(feature = "track-leases")]
lease: orig.lease,
}
}
#[inline]
pub fn filter_map<U: ?Sized, F>(orig: ArcRefMut<T, C>, f: F) -> Option<ArcRefMut<U, C>>
where
F: FnOnce(&mut T) -> Option<&mut U>,
{
Some(ArcRefMut {
value: f(unsafe { &mut *orig.value })?,
guard: orig.guard,
#[cfg(feature = "track-leases")]
lease: orig.lease,
})
}
}
impl<T: ?Sized, C: ?Sized> Deref for ArcRefMut<T, C> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
unsafe { &*self.value }
}
}
impl<T: ?Sized, C: ?Sized> DerefMut for ArcRefMut<T, C> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.value }
}
}
impl<T: ?Sized + Debug, C: ?Sized> Debug for ArcRef<T, C> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
impl<T: ?Sized + Debug, C: ?Sized> Debug for ArcRefMut<T, C> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
impl<T: ?Sized + Debug> Debug for ArcCell<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ArcCell {{ ... }}")
}
}
impl<T: ?Sized + Debug> Debug for AtomicRefCell<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "AtomicRefCell {{ ... }}")
}
}
impl<T: ?Sized> NonBlockingGuardedBorrow<T> for AtomicRefCell<T> {
type Guard<'a>
where
T: 'a,
= AtomicRef<'a, T>;
type BorrowError<'a>
where
T: 'a,
= BorrowError;
fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
self.try_borrow()
}
}
impl<T: ?Sized> NonBlockingGuardedBorrowMut<T> for AtomicRefCell<T> {
type GuardMut<'a>
where
T: 'a,
= AtomicRefMut<'a, T>;
type BorrowMutError<'a>
where
T: 'a,
= BorrowMutError;
fn try_nonblocking_guarded_borrow_mut(
&self,
) -> Result<Self::GuardMut<'_>, Self::BorrowMutError<'_>> {
self.try_borrow_mut()
}
}
impl<T: ?Sized> NonBlockingGuardedMutBorrowMut<T> for AtomicRefCell<T> {
type MutGuardMut<'a>
where
T: 'a,
= &'a mut T;
type MutBorrowMutError<'a>
where
T: 'a,
= Infallible;
fn try_nonblocking_guarded_mut_borrow_mut(
&mut self,
) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
Ok(self.get_mut())
}
}
impl<T: ?Sized> NonBlockingGuardedBorrow<T> for ArcCell<T> {
type Guard<'a>
where
T: 'a,
= AtomicRef<'a, T>;
type BorrowError<'a>
where
T: 'a,
= BorrowError;
fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
self.as_inner().try_borrow()
}
}
impl<T: ?Sized> NonBlockingGuardedBorrowMut<T> for ArcCell<T> {
type GuardMut<'a>
where
T: 'a,
= AtomicRefMut<'a, T>;
type BorrowMutError<'a>
where
T: 'a,
= BorrowMutError;
fn try_nonblocking_guarded_borrow_mut(
&self,
) -> Result<Self::GuardMut<'_>, Self::BorrowMutError<'_>> {
self.as_inner().try_borrow_mut()
}
}
impl<T: ?Sized> NonBlockingGuardedMutBorrowMut<T> for ArcCell<T> {
type MutGuardMut<'a>
where
T: 'a,
= AtomicRefMut<'a, T>;
type MutBorrowMutError<'a>
where
T: 'a,
= BorrowMutError;
fn try_nonblocking_guarded_mut_borrow_mut(
&mut self,
) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
self.as_inner().try_borrow_mut()
}
}
impl<T: ?Sized, C: ?Sized> NonBlockingGuardedBorrow<T> for ArcRef<T, C> {
type Guard<'a>
where
T: 'a,
Self: 'a,
= &'a T;
type BorrowError<'a>
where
T: 'a,
Self: 'a,
= Infallible;
fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
Ok(self)
}
}
impl<T: ?Sized, C: ?Sized> NonBlockingGuardedMutBorrowMut<T> for ArcRef<T, C> {
type MutGuardMut<'a>
where
T: 'a,
Self: 'a,
= &'a mut T;
type MutBorrowMutError<'a>
where
T: 'a,
Self: 'a,
= &'static str;
fn try_nonblocking_guarded_mut_borrow_mut(
&mut self,
) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
Err("cannot mutably borrow an `ArcRef`")
}
}
impl<T: ?Sized, C: ?Sized> NonBlockingGuardedBorrow<T> for ArcRefMut<T, C> {
type Guard<'a>
where
T: 'a,
Self: 'a,
= &'a T;
type BorrowError<'a>
where
T: 'a,
Self: 'a,
= Infallible;
fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
Ok(self)
}
}
impl<T: ?Sized, C: ?Sized> NonBlockingGuardedMutBorrowMut<T> for ArcRefMut<T, C> {
type MutGuardMut<'a>
where
T: 'a,
Self: 'a,
= &'a mut T;
type MutBorrowMutError<'a>
where
T: 'a,
Self: 'a,
= Infallible;
fn try_nonblocking_guarded_mut_borrow_mut(
&mut self,
) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
Ok(self)
}
}