chiark / gitweb /
provide borrowed version
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 15 Nov 2024 16:03:43 +0000 (16:03 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 15 Nov 2024 16:03:43 +0000 (16:03 +0000)
src/lib.rs

index 4b6cceed537903b7c774d367264e9c344ecc69da..ec245ab2432112da226ee0cd3bc6a81800dbda2c 100644 (file)
@@ -67,6 +67,7 @@ mod test;
 use std::collections::HashSet;
 use std::fmt::{self, Debug, Display};
 use std::marker::PhantomData;
+use std::ops::Deref;
 use std::ptr::NonNull;
 
 //---------- public types ----------
@@ -433,17 +434,56 @@ impl NoAliasSingleton {
     pub unsafe fn init() -> Self { NoAliasSingleton {} }
 }
 
-/*
-    /// SAFETY
+//---------- stack ----------
+
+pub struct Borrowed<'t, T: ?Sized> {
+    ptr: Ptr<T>,
+    /// Variance and borrowing:
+    ///
+    life: PhantomData<&'t T>,
+}
+
+impl<'t, T: ?Sized> Borrowed<'t, T> {
+    /// Obtain a `Ptr` from borrowed data
+    ///
+    /// Derefs to `Ptr<T>`.
+    ///
+    /// Call [`.retained()`](Borrowed::retained)
+    /// at the point(s) where it is OK for the `Ptr`s to become invalid.
+    ///
+    /// # SAFETY
+    ///
+    /// You must ensure that the `Ptr` (and all its copies) is only used
+    /// while the `Borrowed` still exists.
     ///
-    /// All copies of the returned `Ptr` become invalid
-    /// when the borrow of `t` ends.
-    /// No-one must use them after that.
+    /// The lifetime cannot be completely checked by the compiler,
+    /// and Rust's drop behaviour can cause the `Ptr` be invalidated
+    /// (for example, by the underlying `T` being dropped, or reborrowed)
+    /// earlier than you might expect.
     ///
-    /// You must not call `deallocate` on the return value.
-TODO lifetime is hard
-    pub unsafe fn new_borrowed<'t>(t: Pin<&'t mut T>) -> Self { todo!() }
-*/
+    /// Using `retained` is recommended:
+    /// it will ensure that `Ptr`s are still live at that point.
+    pub unsafe fn new(t: &mut T) -> Self {
+        Borrowed {
+            ptr: Ptr::from_raw(NonNull::from(t)),
+            life: PhantomData,
+        }
+    }
+
+    /// Prove that a `Borrowed` is still live.
+    ///
+    /// This function is a no-op, in itself.
+    ///
+    /// But calling it assures that the lifetime of the `Borrow`
+    /// extends at least this far.
+    pub fn retained(&self) {
+    }
+}
+
+impl<'t, T> Deref for Borrowed<'t, T> {
+    type Target = Ptr<T>;
+    fn deref(&self) -> &Ptr<T> { &self.ptr }
+}
 
 //---------- helpful impls ----------