diff --git a/packages/generational-box/src/lib.rs b/packages/generational-box/src/lib.rs index 467868fb1..b8fdee94b 100644 --- a/packages/generational-box/src/lib.rs +++ b/packages/generational-box/src/lib.rs @@ -485,309 +485,6 @@ impl MemoryLocation { _marker: PhantomData, } } - - #[track_caller] - fn try_borrow( - &self, - #[cfg(any(debug_assertions, feature = "debug_ownership"))] - created_at: &'static std::panic::Location<'static>, - ) -> Result, BorrowError> { - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - self.0 - .borrowed_at - .borrow_mut() - .push(std::panic::Location::caller()); - match self.0.data.try_borrow() { - Ok(borrow) => match Ref::filter_map(borrow, |any| any.as_ref()?.downcast_ref::()) { - Ok(reference) => Ok(GenerationalRef { - inner: reference, - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow: GenerationalRefBorrowInfo { - borrowed_at: std::panic::Location::caller(), - borrowed_from: self.0, - }, - }), - Err(_) => Err(BorrowError::Dropped(ValueDroppedError { - #[cfg(any(debug_assertions, feature = "debug_ownership"))] - created_at, - })), - }, - Err(_) => Err(BorrowError::AlreadyBorrowedMut(AlreadyBorrowedMutError { - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrowed_mut_at: self.0.borrowed_mut_at.get().unwrap(), - })), - } - } - - #[track_caller] - fn try_borrow_mut( - &self, - #[cfg(any(debug_assertions, feature = "debug_ownership"))] - created_at: &'static std::panic::Location<'static>, - ) -> Result, BorrowMutError> { - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - { - self.0 - .borrowed_mut_at - .set(Some(std::panic::Location::caller())); - } - match self.0.data.try_borrow_mut() { - Ok(borrow_mut) => { - match RefMut::filter_map(borrow_mut, |any| any.as_mut()?.downcast_mut::()) { - Ok(reference) => Ok(GenerationalRefMut { - inner: reference, - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow: GenerationalRefMutBorrowInfo { - borrowed_from: self.0, - }, - }), - Err(_) => Err(BorrowMutError::Dropped(ValueDroppedError { - #[cfg(any(debug_assertions, feature = "debug_ownership"))] - created_at, - })), - } - } - Err(_) => Err(BorrowMutError::AlreadyBorrowed(AlreadyBorrowedError { - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrowed_at: self.0.borrowed_at.borrow().clone(), - })), - } - } -} - -#[derive(Debug, Clone)] -/// An error that can occur when trying to borrow a value. -pub enum BorrowError { - /// The value was dropped. - Dropped(ValueDroppedError), - /// The value was already borrowed mutably. - AlreadyBorrowedMut(AlreadyBorrowedMutError), -} - -impl Display for BorrowError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - BorrowError::Dropped(error) => Display::fmt(error, f), - BorrowError::AlreadyBorrowedMut(error) => Display::fmt(error, f), - } - } -} - -impl Error for BorrowError {} - -#[derive(Debug, Clone)] -/// An error that can occur when trying to borrow a value mutably. -pub enum BorrowMutError { - /// The value was dropped. - Dropped(ValueDroppedError), - /// The value was already borrowed. - AlreadyBorrowed(AlreadyBorrowedError), - /// The value was already borrowed mutably. - AlreadyBorrowedMut(AlreadyBorrowedMutError), -} - -impl Display for BorrowMutError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - BorrowMutError::Dropped(error) => Display::fmt(error, f), - BorrowMutError::AlreadyBorrowedMut(error) => Display::fmt(error, f), - BorrowMutError::AlreadyBorrowed(error) => Display::fmt(error, f), - } - } -} - -impl Error for BorrowMutError {} - -/// An error that can occur when trying to use a value that has been dropped. -#[derive(Debug, Copy, Clone)] -pub struct ValueDroppedError { - #[cfg(any(debug_assertions, feature = "debug_ownership"))] - created_at: &'static std::panic::Location<'static>, -} - -impl Display for ValueDroppedError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("Failed to borrow because the value was dropped.")?; - #[cfg(any(debug_assertions, feature = "debug_ownership"))] - f.write_fmt(format_args!("created_at: {}", self.created_at))?; - Ok(()) - } -} - -impl std::error::Error for ValueDroppedError {} - -/// An error that can occur when trying to borrow a value that has already been borrowed mutably. -#[derive(Debug, Copy, Clone)] -pub struct AlreadyBorrowedMutError { - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrowed_mut_at: &'static std::panic::Location<'static>, -} - -impl Display for AlreadyBorrowedMutError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("Failed to borrow because the value was already borrowed mutably.")?; - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - f.write_fmt(format_args!("borrowed_mut_at: {}", self.borrowed_mut_at))?; - Ok(()) - } -} - -impl std::error::Error for AlreadyBorrowedMutError {} - -/// An error that can occur when trying to borrow a value mutably that has already been borrowed immutably. -#[derive(Debug, Clone)] -pub struct AlreadyBorrowedError { - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrowed_at: Vec<&'static std::panic::Location<'static>>, -} - -impl Display for AlreadyBorrowedError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("Failed to borrow mutably because the value was already borrowed immutably.")?; - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - f.write_str("borrowed_at:")?; - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - for location in self.borrowed_at.iter() { - f.write_fmt(format_args!("\t{}", location))?; - } - Ok(()) - } -} - -impl std::error::Error for AlreadyBorrowedError {} - -/// A reference to a value in a generational box. -pub struct GenerationalRef { - inner: Ref<'static, T>, - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow: GenerationalRefBorrowInfo, -} - -impl GenerationalRef { - /// Map one ref type to another. - pub fn map(orig: GenerationalRef, f: F) -> GenerationalRef - where - F: FnOnce(&T) -> &U, - { - GenerationalRef { - inner: Ref::map(orig.inner, f), - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow: GenerationalRefBorrowInfo { - borrowed_at: orig.borrow.borrowed_at, - borrowed_from: orig.borrow.borrowed_from, - }, - } - } - - /// Filter one ref type to another. - pub fn filter_map(orig: GenerationalRef, f: F) -> Option> - where - F: FnOnce(&T) -> Option<&U>, - { - let Self { - inner, - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow, - } = orig; - Ref::filter_map(inner, f).ok().map(|inner| GenerationalRef { - inner, - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow: GenerationalRefBorrowInfo { - borrowed_at: borrow.borrowed_at, - borrowed_from: borrow.borrowed_from, - }, - }) - } -} - -impl Deref for GenerationalRef { - type Target = T; - - fn deref(&self) -> &Self::Target { - self.inner.deref() - } -} - -#[cfg(any(debug_assertions, feature = "debug_borrows"))] -struct GenerationalRefBorrowInfo { - borrowed_at: &'static std::panic::Location<'static>, - borrowed_from: &'static MemoryLocationInner, -} - -#[cfg(any(debug_assertions, feature = "debug_borrows"))] -impl Drop for GenerationalRefBorrowInfo { - fn drop(&mut self) { - self.borrowed_from - .borrowed_at - .borrow_mut() - .retain(|location| std::ptr::eq(*location, self.borrowed_at as *const _)); - } -} - -/// A mutable reference to a value in a generational box. -pub struct GenerationalRefMut { - inner: RefMut<'static, T>, - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow: GenerationalRefMutBorrowInfo, -} - -impl GenerationalRefMut { - /// Map one ref type to another. - pub fn map(orig: GenerationalRefMut, f: F) -> GenerationalRefMut - where - F: FnOnce(&mut T) -> &mut U, - { - GenerationalRefMut { - inner: RefMut::map(orig.inner, f), - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow: orig.borrow, - } - } - - /// Filter one ref type to another. - pub fn filter_map(orig: GenerationalRefMut, f: F) -> Option> - where - F: FnOnce(&mut T) -> Option<&mut U>, - { - let Self { - inner, - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow, - } = orig; - RefMut::filter_map(inner, f) - .ok() - .map(|inner| GenerationalRefMut { - inner, - #[cfg(any(debug_assertions, feature = "debug_borrows"))] - borrow, - }) - } -} - -impl Deref for GenerationalRefMut { - type Target = T; - - fn deref(&self) -> &Self::Target { - self.inner.deref() - } -} - -impl DerefMut for GenerationalRefMut { - fn deref_mut(&mut self) -> &mut Self::Target { - self.inner.deref_mut() - } -} - -#[cfg(any(debug_assertions, feature = "debug_borrows"))] -struct GenerationalRefMutBorrowInfo { - borrowed_from: &'static MemoryLocationInner, -} - -#[cfg(any(debug_assertions, feature = "debug_borrows"))] -impl Drop for GenerationalRefMutBorrowInfo { - fn drop(&mut self) { - self.borrowed_from.borrowed_mut_at.take(); - } } /// Owner: Handles dropping generational boxes. The owner acts like a runtime lifetime guard. Any states that you create with an owner will be dropped when that owner is dropped.