From: Ian Jackson Date: Fri, 15 Nov 2024 16:03:43 +0000 (+0000) Subject: provide borrowed version X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=9f468c71594c3c293da31e0d83f2cedcd9dd1921;p=manually-boxed provide borrowed version --- diff --git a/src/lib.rs b/src/lib.rs index 4b6ccee..ec245ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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, + /// Variance and borrowing: + /// + life: PhantomData<&'t T>, +} + +impl<'t, T: ?Sized> Borrowed<'t, T> { + /// Obtain a `Ptr` from borrowed data + /// + /// Derefs to `Ptr`. + /// + /// 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; + fn deref(&self) -> &Ptr { &self.ptr } +} //---------- helpful impls ----------