//!
//! * Following Rust's aliasing rules,
//! which are (for our purposes) stricter than C's.
-//! The library should prevent accidental creation
+//! This library aims to prevent accidental creation
//! of overlapping `&mut`, for example.
//!
//! * Threadsafety; `Send` and `Sync`.
//! (The caller must still make sure not to free an object
//! that another thread may be using, of course.)
//!
-//! * Soundness in the face of panics, including in methods
+//! * Soundness in the face of panics, including panics from methods
//! of the contained type `T`, eg `T`'s `Drop` impl.
//!
-//! * "`Drop` footguns", and others, sometimes found in unsafe code.
+//! * "`Drop` footguns", and the like, which lurk in Unsafe Rust.
//!
//! ### Soundness
//!
//! than is usual for a Rust API.
//!
//! In practice this means that in a real program,
-//! correctness is likely to depend on the behaviour
-//! of even nominally "safe" code.
+//! memory-safety is likely to depend on the correctness
+//! of much nominally "safe" code.
//! The rules have been chosen pragmatically,
//! to minimise the proportion of the caller that needs
//! to be *actually marked* with `unsafe`.
/// To mutably access the data of more than one node at once,
/// use
/// [`IsTokenMut::multi_static`],
-/// [`IsTokenMut::multi_dynamic`],
-/// or for manual aliasing checks,
+/// [`IsTokenMut::multi_dynamic`].
+///
+/// To avoid runtime aliasing checks, and take manual control of aliasing,
+/// you can
/// [`.borrow_mut()`](Ptr::borrow_mut()) with
/// [`TokenMut::new_unchecked()`].
+/// Or,
+/// `p`[`.as_ptr()`](Ptr::as_ptr)[`.as_ref()`](NonNull::as_ref())
+/// /
+/// `p`[`.as_ptr()`](Ptr::as_ptr)[`.as_mut()`](NonNull::as_mut()).
///
/// This type is `Copy`. Copying it (or, indeed, cloning it)
/// does not copy the underlying data.
/// [`Ptr::borrow()`]/[`borrow_mut()`](Ptr::borrow_mut)
/// multiple times, retaining and using all the resulting references.
///
+ /// For another approach,
+ /// see [`Ptr::as_ptr()`].
+ ///
/// # SAFETY
///
/// The calls to `borrow[_mut]` that this enables must not violate
/// Rust's rules. Checking that is up to you.
- ///
+ ///
/// So, all of the `Ptr` you `borrow_mut` must be distinct,
/// and they must be distinct from your `borrow`s.
/// Violating this rule is instant undefined behaviour,
/// even if you never read or write the resulting reference(s).
+ ///
+ /// Also, it is up to you to make sure you don't free the data to soon.
pub unsafe fn new_unchecked() -> Self { TokenMut(PhantomData) }
}
/// If `Ptr` was made with `new_heap` or `From<Box<_>>`,
/// this pointer has the same properties as `Box`'s.
/// But of course many copies may exist.
+ ///
+ /// # Obtaining references
+ ///
+ /// You may call
+ /// [`.as_ref()`](NonNull::as_ref)
+ /// or
+ /// [`.as_mut()`](NonNull::as_mut)
+ /// on the returned `NonNull`,
+ /// to get `&T` or `&mut T`.
+ ///
+ /// This is sound iff there are no conflicting borrows,
+ /// and you know you won't be freeing the data too soon.
+ /// If you do this, you take responsibility
+ /// for following Rust's aliasing rules.
+ ///
+ /// This approach is semantically equivalent to using
+ /// [`TokenMut::new_unchecked()`].
pub fn as_ptr(self) -> NonNull<T> {
self.ptr
}