chiark / gitweb /
wip
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 14 Nov 2024 16:02:09 +0000 (16:02 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 14 Nov 2024 21:49:13 +0000 (21:49 +0000)
src/lib.rs

index 5c0a926374ca73939a3e3be5ac81518010655660..384474bf3aa82e4c22e656cb6a0c4d242f733f94 100644 (file)
@@ -1,9 +1,25 @@
 
 // Not Clone or Copy
-pub struct NoAlias {
+pub struct NoAliasSingleton {
     _unsafe_to_construct: (),
 }
 
+impl Deref for NoAliasSingleton {
+    type Target = NoAlias<'a>;
+    fn deref(
+}    
+
+
+// Not Clone or Copy
+pub struct NoAlias<a'>(
+    PhantomData(&mut NoAliasSingleton),
+);
+
+impl<'a> NoAlias<'a> {
+    pub fn reborrow<'s: 'a>(&'s mut self) -> NoAlias<'a> {
+    }
+}
+
 #[derive(Copy)]
 pub struct Ptr<T> {
     // invariant over T
@@ -13,6 +29,7 @@ pub struct Ptr<T> {
 impl<T> Ptr<T> {
     pub fn new(t: T) -> Self { .. }
 
+/*
     /// SAFETY
     ///
     /// All copies of the returned `Ptr` become invalid
@@ -20,15 +37,18 @@ impl<T> Ptr<T> {
     /// No-one must use them after that.
     ///
     /// You must not call `deallocate` on the return value.
-    pub unsafe fn new_stack<'t>(
-        t: Pin<&'t mut T>,
-    ) -> Self { .. }
+TODO lifetime is hard
+    pub unsafe fn new_borrowed<'t>(t: Pin<&'t mut T>) -> Self { .. }
+*/
 
+    #[inline]
     pub fn borrow(self, g: &NoAlias) -> Ref<T> { .. }
 
-    // TODO ZST
+    #[inline]
     pub fn borrow_mut(self, g: &mut NoAlias) -> RefMut<T> { .. }
 
+    /// 
+    ///
     /// # SAFETY
     ///
     /// All copies of `self` will be invalidated.
@@ -40,7 +60,7 @@ impl<T> Ptr<T> {
     /// ("used" means passed to any method in this library).
     ///
     /// (The compiler will check that no borrows are live.)
-    pub unsafe fn free(self, g: &mut NoAlias) { .. }
+    pub unsafe fn free(self, g: &mut NoAlias) -> T { .. }
 }
 
 impl<T> Deref for Ref<T> {
@@ -86,9 +106,65 @@ pub fn add(left: u64, right: u64) -> u64 {
 mod tests {
     use super::*;
 
+    mod list {
+        pub struct Node<T> {
+            back: Option<Ptr<Node>>,
+            next: Option<Ptr<Node>>,
+            pub data: T,
+        }
+
+        pub struct List<T> {
+            head: Option<Ptr<Node>>,
+            tail: Option<Ptr<Node>>,
+            noalias: NoAliasSingleton,
+        }
+
+        impl<T> List<T> {
+            pub fn new() -> Self {
+                let noalias = unsafe { NoAliasSingleton::new() };
+                List { head: None, tail: None, noalias }
+            }
+
+            pub fn append(&mut self, data: T) {
+                let node = Node {
+                    back: self.head,
+                    next: None,
+                    data,
+                };
+                let node = Ptr::new_heap(node);
+                self.tail = node;
+                if self.head == None { self.head = node };
+            }
+
+            pub fn pop_front(&mut self) -> Option<T> {
+                let noalias = &mut self.noalias;
+                let deleting = self.head?;
+                let new_head = node.borrow(noalias);
+                self.head = new_head;
+                if let Some(new_head) = new_head {
+                    new_head.borrow_mut(&mut self.noalias).back = None;
+                } else {
+                    self.tail = None;
+                }
+                deleting.free(noalias)
+            }
+        }
+
+        impl<T> Drop for List<T> {
+            fn drop(&mut self) {
+                while let Some(_) = self.pop_front() { }
+            }
+        }
+    }
+
     #[test]
-    fn 
-        let result = add(2, 2);
-        assert_eq!(result, 4);
+    fn demo() {
+        let l = List::new();
+        drop(l);
+
+        let mut l = List::new();
+        l.append(format!("hi"));
+        l.append(format!("ho"));
+        drop(l);
     }
 }