chiark / gitweb /
compiles again
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 14 Nov 2024 17:03:16 +0000 (17:03 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 14 Nov 2024 21:49:40 +0000 (21:49 +0000)
src/lib.rs

index f61f7a211034c5fbe5aa4c4449ede7cedb0bd0f7..e55fa8f402cafbcbc98a37265c9ffc76a6f6cd96 100644 (file)
@@ -9,14 +9,24 @@ pub struct NoAliasSingleton {
     _unsafe_to_construct: (),
 }
 
-impl NoAliasSingleton {
-    pub fn ref_token<'a>(&'a mut self) -> RefToken<'a> {
-        RefToken(PhantomData)
-    }
-    pub fn mut_token<'a>(&'a mut self) -> MutToken<'a> {
+pub unsafe trait IsRefToken<'a> {
+    fn ref_token(&'a self) -> RefToken<'a> { RefToken(PhantomData) }
+}
+pub unsafe trait IsMutToken<'a>: IsRefToken<'a> {
+    fn mut_token<'r, 's>(&'s mut self) -> MutToken<'r>
+    where 's: 'r, 'a: 'r,
+    {
         MutToken(PhantomData)
     }
 }
+unsafe impl<'a> IsRefToken<'a> for NoAliasSingleton {}
+unsafe impl<'a> IsMutToken<'a> for NoAliasSingleton {}
+unsafe impl<'a> IsRefToken<'a> for RefToken<'a> {}
+unsafe impl<'a> IsRefToken<'a> for MutToken<'a> {}
+unsafe impl<'a> IsMutToken<'a> for MutToken<'a> {}
+unsafe impl<'a, A: IsRefToken<'a>> IsRefToken<'a> for &'a A {}
+//unsafe impl<'s, 'l: 's, A: IsMutToken<'s>> IsRefToken<'s> for &'l mut A {}
+//unsafe impl<'s, 'l: 's, A: IsMutToken<'s>> IsMutToken<'s> for &'l mut A {}
 
 /*impl Deref for 
     type Target = NoAlias<'a>;
@@ -32,11 +42,11 @@ pub struct RefToken<'a>(
 pub struct MutToken<'a>(
     PhantomData<&'a mut NoAliasSingleton>,
 );
-impl<'a> MutToken<'a>{
+/*impl<'a> MutToken<'a>{
     pub fn ref_token(&'a self) -> RefToken<'a> {
         RefToken(PhantomData)
     }
-}
+}*/
 
 /*impl<'a> MutToken<'a> {
     pub fn reborrow<'s: 'a>(&'s mut self) -> MutToken<'a> {
@@ -71,10 +81,12 @@ TODO lifetime is hard
 */
 
     #[inline]
-    pub fn borrow<'na>(self, na: &'na RefToken<'na>) -> &'na T { todo!() }
+    pub fn borrow<'a>(self, tok: impl IsRefToken<'a>) -> &'a T {
+        todo!()
+    }
 
     #[inline]
-    pub fn borrow_mut<'na>(self, g: &mut MutToken<'na>) -> &'na mut T {
+    pub fn borrow_mut<'a>(self, tok: impl IsMutToken<'a>) -> &'a mut T {
         todo!()
     }
 
@@ -96,7 +108,10 @@ TODO lifetime is hard
     /// ("used" means passed to any method in this library).
     ///
     /// (The compiler will check that no borrows are live.)
-    pub unsafe fn free_heap(self, g: &mut MutToken) -> T { todo!() }
+    #[inline]
+    pub unsafe fn free_heap<'a>(self, tok: impl IsMutToken<'a>) -> T {
+        todo!()
+    }
 }
 
 /*struct MultiAccessor<'a, R, const N: usize> {
@@ -136,6 +151,7 @@ impl MultiAccessor<'a, R, const N: usize> {
 #[cfg(test)]
 mod tests {
     use super::*;
+    use std::fmt::Write as _;
 
     mod list {
         use super::*;
@@ -172,12 +188,11 @@ mod tests {
             pub fn front(&self) -> Option<&T> {
                 let tok = self.noalias.ref_token();
                 let head = self.head?;
-                Some(&head.borrow(&tok).data)
+                Some(&head.borrow(tok).data)
             }
 
-            pub fn front_mut(&mut self) -> Option<&T> {
-                let mut tok = self.noalias.mut_token();
-                let tok = &mut tok;
+            pub fn front_mut(&mut self) -> Option<&mut T> {
+                let tok = self.noalias.mut_token();
                 let head = self.head?;
                 Some(&mut head.borrow_mut(tok).data)
             }
@@ -194,20 +209,20 @@ mod tests {
 
             // We wouldn't do this, since it's daft, but
             // it lets us demonstrate passing a NoAlias.
-            fn pop_front_inner(
-                noalias: MutToken,
+            fn pop_front_inner<'a>(
+                mut tok: MutToken<'a>,
                 head: &mut Option<Ptr<Node<T>>>,
                 tail: &mut Option<Ptr<Node<T>>>,
             ) -> Option<T> {
                 let deleting = (*head)?;
-                let new_head = deleting.borrow(&noalias.ref_token()).next;
+                let new_head = deleting.borrow(tok.mut_token()).next;
                 *head = new_head;
                 if let Some(new_head) = new_head {
-                    new_head.borrow_mut(noalias).back = None;
+                    new_head.borrow_mut(tok.mut_token()).back = None;
                 } else {
                     *tail = None;
                 }
-                let deleted = unsafe { deleting.free_heap(noalias) };
+                let deleted = unsafe { deleting.free_heap(tok) };
                 Some(deleted.data)
             }
         }
@@ -215,7 +230,7 @@ mod tests {
         impl<T> Drop for List<T> {
             fn drop(&mut self) {
                 while let Some(_) = Self::pop_front_inner(
-                    self.noalias.as_mut(),
+                    self.noalias.mut_token(),
                     &mut self.head,
                     &mut self.tail,
                 ) { }
@@ -234,7 +249,8 @@ mod tests {
         let mut l = List::new();
         l.append(format!("hi"));
         l.append(format!("ho"));
-        assert_eq!(l.front(), Some("hi"));
+        write!(l.front_mut().unwrap(), "!").unwrap();
+        assert_eq!(l.front(), Some(&format!("hi!")));
         drop(l);
     }
 }