use std::{ fmt::{Debug, Display}, ops::{Deref, DerefMut}, }; /// A reference to a value in a generational box. pub struct GenerationalRef { pub(crate) inner: R, #[cfg(any(debug_assertions, feature = "debug_borrows"))] pub(crate) borrow: GenerationalRefBorrowInfo, } impl> GenerationalRef { pub(crate) fn new( inner: R, #[cfg(any(debug_assertions, feature = "debug_borrows"))] borrow: GenerationalRefBorrowInfo, ) -> Self { Self { inner, #[cfg(any(debug_assertions, feature = "debug_borrows"))] borrow, } } } impl> Debug for GenerationalRef { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.inner.deref().fmt(f) } } impl> Display for GenerationalRef { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.inner.deref().fmt(f) } } impl> Deref for GenerationalRef { type Target = T; fn deref(&self) -> &Self::Target { self.inner.deref() } } #[cfg(any(debug_assertions, feature = "debug_borrows"))] /// Information about a borrow. pub struct GenerationalRefBorrowInfo { pub(crate) borrowed_at: &'static std::panic::Location<'static>, pub(crate) borrowed_from: &'static crate::MemoryLocationBorrowInfo, pub(crate) created_at: &'static std::panic::Location<'static>, } #[cfg(any(debug_assertions, feature = "debug_borrows"))] impl Drop for GenerationalRefBorrowInfo { fn drop(&mut self) { self.borrowed_from .borrowed_at .write() .retain(|location| !std::ptr::eq(*location, self.borrowed_at as *const _)); } } /// A mutable reference to a value in a generational box. pub struct GenerationalRefMut { pub(crate) inner: W, #[cfg(any(debug_assertions, feature = "debug_borrows"))] pub(crate) borrow: GenerationalRefBorrowMutGuard, } impl> GenerationalRefMut { pub(crate) fn new( inner: R, #[cfg(any(debug_assertions, feature = "debug_borrows"))] borrow: GenerationalRefMutBorrowInfo, ) -> Self { Self { inner, #[cfg(any(debug_assertions, feature = "debug_borrows"))] borrow: borrow.into(), } } } 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"))] /// Information about a mutable borrow. pub struct GenerationalRefMutBorrowInfo { /// The location where the borrow occurred. pub(crate) borrowed_from: &'static crate::MemoryLocationBorrowInfo, pub(crate) created_at: &'static std::panic::Location<'static>, } #[cfg(any(debug_assertions, feature = "debug_borrows"))] pub(crate) struct GenerationalRefBorrowMutGuard { borrow_info: GenerationalRefMutBorrowInfo, } #[cfg(any(debug_assertions, feature = "debug_borrows"))] impl From for GenerationalRefBorrowMutGuard { fn from(borrow_info: GenerationalRefMutBorrowInfo) -> Self { Self { borrow_info } } } #[cfg(any(debug_assertions, feature = "debug_borrows"))] impl Drop for GenerationalRefBorrowMutGuard { fn drop(&mut self) { self.borrow_info .borrowed_from .borrowed_mut_at .write() .take(); } }