From: Ian Jackson Date: Thu, 14 Nov 2024 22:07:27 +0000 (+0000) Subject: ergonomic X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=677cb4db680c5f657bc678fb766aff50e8e8cba5;p=manually-boxed ergonomic --- diff --git a/src/lib.rs b/src/lib.rs index 6b886fb..d1c4384 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -248,8 +248,10 @@ pub struct MultiStatic<'a, L> { l: L, } -fn forbid_alias(this: &T, new: NonNull<()>) -> Result<(), BorrowConflict> { - if NonNull::from(this) == new.cast() { return Err(BorrowConflict) } +fn forbid_alias(this: *const (), new: NonNull<()>) + -> Result<(), BorrowConflict> +{ + if this == new.as_ptr() { return Err(BorrowConflict) } Ok(()) } @@ -265,7 +267,7 @@ unsafe impl MultiStaticList for () { Ok(()) } } -unsafe impl MultiStaticList for (L, &T) { +unsafe impl MultiStaticList for (L, *const ()) { fn alias_check_ref(&self, p: NonNull<()>) -> Result<(), BorrowConflict> { self.0.alias_check_ref(p) } @@ -274,51 +276,53 @@ unsafe impl MultiStaticList for (L, &T) { self.0.alias_check_mut(p) } } -unsafe impl MultiStaticList for (L, &mut T) { +unsafe impl MultiStaticList for (L, NonNull<()>) { fn alias_check_ref(&self, p: NonNull<()>) -> Result<(), BorrowConflict> { - forbid_alias(&*self.1, p)?; + forbid_alias(self.1.as_ptr(), p)?; self.0.alias_check_ref(p) } fn alias_check_mut(&self, p: NonNull<()>) -> Result<(), BorrowConflict> { - forbid_alias(&*self.1, p)?; + forbid_alias(self.1.as_ptr(), p)?; self.0.alias_check_mut(p) } } impl<'a, L: MultiStaticList> MultiStatic<'a, L> { pub fn borrow<'r, T>(self, p: Ptr) -> Result< - MultiStatic<'a, (L, &'r T)>, + (&'r T, MultiStatic<'a, (L, *const ())>), Self > where 'a: 'r { match self.l.alias_check_ref(p.ptr.cast()) { Err(BorrowConflict) => Err(self), - Ok(()) => Ok(MultiStatic { - tok: self.tok, - l: (self.l, unsafe { p.ptr.as_ref() }), - }) + Ok(()) => Ok(( + unsafe { p.ptr.as_ref() }, + MultiStatic { + tok: self.tok, + l: (self.l, p.ptr.cast().as_ptr()), + } + )) } } pub fn borrow_mut<'r, T>(self, mut p: Ptr) -> Result< - MultiStatic<'a, (L, &'r mut T)>, + (&'r mut T, MultiStatic<'a, (L, NonNull<()>)>), Self > where 'a: 'r { match self.l.alias_check_mut(p.ptr.cast()) { Err(BorrowConflict) => Err(self), - Ok(()) => Ok(MultiStatic { - tok: self.tok, - l: (self.l, unsafe { p.ptr.as_mut() }), - }) + Ok(()) => Ok(( + unsafe { p.ptr.as_mut() }, + MultiStatic { + tok: self.tok, + l: (self.l, p.ptr.cast()), + }, + )) } } - - pub fn finish(self) -> L { - self.l - } } pub struct MultiRuntime<'a> { diff --git a/src/test/demo.rs b/src/test/demo.rs index 5514e75..5d57cb0 100644 --- a/src/test/demo.rs +++ b/src/test/demo.rs @@ -89,21 +89,15 @@ impl List { let multi = self.noalias.mut_token().multi_static(); - let Ok(multi) = multi.borrow_mut(head) + let Ok((head, multi)) = multi.borrow_mut(head) else { unsafe { unreachable_unchecked() } }; let tail = unsafe { self.tail.unwrap_unchecked() }; - match multi.borrow_mut(tail) { - Ok(y) => { - let (((), head), tail) = y.finish(); - HeadAndTail::Both(&mut head.data, &mut tail.data) - }, - Err(n) => { - let ((), head) = n.finish(); - HeadAndTail::One(&mut head.data) - } - } + let Ok((tail, _)) = multi.borrow_mut(tail) + else { return HeadAndTail::One(&mut head.data) }; + + HeadAndTail::Both(&mut head.data, &mut tail.data) } pub fn all(&self) -> impl Iterator {