/// and `&`-references to them.
pub unsafe trait IsRefToken<'a> {
/// Obtain a new ZST token from something that might be a real object.
+ #[inline]
fn ref_token(&'a self) -> RefToken<'a> {
RefToken(PhantomData)
}
/// and `&mut`-references to them.
pub unsafe trait IsMutToken<'a>: IsRefToken<'a> {
/// Obtain a new ZST token from something that might be a real object.
+ #[inline]
fn mut_token<'r, 's>(&'s mut self) -> MutToken<'r>
where 's: 'r, 'a: 'r,
{
MutToken(PhantomData)
}
+
+ fn multi_static<'r, 's>(&'s mut self) -> MultiStatic<'r, ()>
+ where 's: 'r, 'a: 'r,
+ {
+ MultiStatic {
+ tok: self.mut_token(),
+ l: (),
+ }
+ }
}
unsafe impl<'a> IsRefToken<'a> for NoAliasSingleton {}
unsafe impl<'a> IsMutToken<'a> for NoAliasSingleton {}
PhantomData<&'a mut NoAliasSingleton>,
);
+impl<'a> MutToken<'a> {
+ ///
+ ///
+ /// SAFETY
+ ///
+ fn new_unchecked() -> Self { MutToken(PhantomData) }
+}
+
pub struct Ptr<T> {
/// # SAFETY
///
self.ptr
}
- ///
+ /// Frees a `Ptr` that was made with `new_heap`
///
/// # SAFETY
///
+ /// `self` must have come from `new_heap`.
+ ///
/// All copies of `self` will be invalidated.
///
/// So either no copies may exist any longer,
}
}
-/*struct MultiAccessor<'a, R, const N: usize> {
-}*/
-
impl NoAliasSingleton {
/// Initialise by creating the singleton for alias checking
///
pub unsafe fn init() -> Self { NoAliasSingleton {} }
}
+pub struct BorrowConflict;
+
+pub struct MultiStatic<'a, L> {
+ tok: MutToken<'a>,
+ l: L,
+}
+
+fn forbid_alias<T>(this: &T, new: *const ()) -> Result<(), BorrowConflict> {
+ let this = this as *const T as *const ();
+ if this == new { return Err(BorrowConflict) }
+ Ok(())
+}
+
+pub trait MultiStaticList {
+ fn alias_check_ref(&self, p: *const ()) -> Result<(), BorrowConflict>;
+ fn alias_check_mut(&self, p: *const ()) -> Result<(), BorrowConflict>;
+}
+impl MultiStaticList for () {
+ fn alias_check_ref(&self, p: *const ()) -> Result<(), BorrowConflict> {
+ Ok(())
+ }
+ fn alias_check_mut(&self, p: *const ()) -> Result<(), BorrowConflict> {
+ Ok(())
+ }
+}
+impl<T, L: MultiStaticList> MultiStaticList for (L, &T) {
+ fn alias_check_ref(&self, p: *const ()) -> Result<(), BorrowConflict> {
+ self.0.alias_check_ref(p)
+ }
+ fn alias_check_mut(&self, p: *const ()) -> Result<(), BorrowConflict> {
+ forbid_alias(self.1, p)?;
+ self.0.alias_check_mut(p)
+ }
+}
+impl<T, L: MultiStaticList> MultiStaticList for (L, &mut T) {
+ fn alias_check_ref(&self, p: *const ()) -> Result<(), BorrowConflict> {
+ forbid_alias(&*self.1, p)?;
+ self.0.alias_check_ref(p)
+ }
+ fn alias_check_mut(&self, p: *const ()) -> Result<(), BorrowConflict> {
+ forbid_alias(&*self.1, p)?;
+ self.0.alias_check_mut(p)
+ }
+}
+
+impl<'a, L: MultiStaticList> MultiStatic<'a, L> {
+ pub fn borrow<'r, T>(self, p: Ptr<T>) -> Result<
+ MultiStatic<'a, (L, &'r T)>,
+ BorrowConflict
+ >
+ where 'a: 'r
+ {
+ self.l.alias_check_ref(p.ptr.as_ptr() as *const ())?;
+ Ok(MultiStatic {
+ tok: self.tok,
+ l: (self.l, unsafe { p.ptr.as_ref() }),
+ })
+ }
+
+ pub fn borrow_mut<'r, T>(self, mut p: Ptr<T>) -> Result<
+ MultiStatic<'a, (L, &'r mut T)>,
+ BorrowConflict
+ >
+ where 'a: 'r
+ {
+ self.l.alias_check_mut(p.ptr.as_ptr() as *const ())?;
+ Ok(MultiStatic {
+ tok: self.tok,
+ l: (self.l, unsafe { p.ptr.as_mut() }),
+ })
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;