use std::collections::HashSet;
use std::fmt::{self, Debug, Display};
use std::marker::PhantomData;
+use std::ops::Deref;
use std::ptr::NonNull;
//---------- public types ----------
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 ----------