From 4df4a24815747dbef62afb23d0141f15f0b2a345 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Thu, 14 Nov 2024 15:29:17 +0000 Subject: [PATCH] wip --- src/lib.rs | 61 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 24b6fe1..65e46f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,14 +24,9 @@ impl Ptr { t: Pin<&'t mut T>, ) -> Self { .. } - pub fn ref_(self, g: &'a NoAlias) -> &'a T { .. } + pub fn borrow(self, g: &NoAlias) -> Ref { .. } - pub fn mut_(self, g: &'a NoAlias) -> &'a mut T { - // SAFETY - // - // 1. - .. - } + pub fn borrow_mut(self, g: &mut NoAlias) -> RefMut { .. } /// # SAFETY /// @@ -43,32 +38,44 @@ impl Ptr { /// /// ("used" means passed to any method in this library). /// - /// (The compiler will check that no borrows - pub unsafe fn free<'g: 'a>(self, : &'g mut NoAlias) { .. } + /// (The compiler will check that no borrows are live.) + pub unsafe fn free(self, g: &mut NoAlias) { .. } +} + +impl Deref for Ref { + type Target = T; +} +impl DerefMut for RefMut { + type Target = T; +} + +struct MultiAccessor<'a, R, const N: usize> { } impl NoAlias { /// # SAFETY /// - /// You must ensure that there is only ever one - /// `NoAlias` within the whole program. - pub unsafe fn new() -> Self { .. } - - pub fn scope(f: impl FnOnce(&mut NoAlias) -> R) -> R { - /// SAFETY - /// - /// `f` doesn't control the lifetime - - /// as far as it's concerned, is independent from any other - /// So it can't mix up *this* NoAlias with any other. - let g = unsafe { NoAlias::new() }; - f(g) - } - - pub fn multi_ref<'aa>( - &'aa mut self, - ref_: [ + /// There must be only one `NoAlias` used with each `Ptr`. + /// + /// That is, it is unsound to use the same `Ptr` (or any copy of it) + /// with two (or more) different `NoAlias`es. + /// + /// The easiest way to do this is to have only one `NoAlias`. + /// + /// If this rule is violated, `borrow` and `borrow_mut` can be instant-UB. + // + // I haven't been able to think of a practical safe API, + // but one only needs about 1 call to init_unchecked. + pub unsafe fn init_unchecked() -> Self { .. } + + pub fn multi(&mut self) -> MultiAccessor<(), 0> { .. } +} + +impl MultiAccessor<'a, R, const N: usize> { + pub fn finish(self) -> R { .. } + + pub fn borrow(self, p: - pub fn multi<'aa: 'a>(self, arena: &'aa mut NoAlias) -> &mut { .. } pub fn add(left: u64, right: u64) -> u64 { left + right -- 2.30.2