// 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
impl<T> Ptr<T> {
pub fn new(t: T) -> Self { .. }
+/*
/// SAFETY
///
/// All copies of the returned `Ptr` become invalid
/// 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.
/// ("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> {
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);
}
}