1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
use core::ptr::NonNull;

use crate::Reference;

/// A smart pointer which holds a "deferred reference" to an instance of type `T: ?Sized`.
/// It has all the properties of a normal reference (`&T` or `&mut T`),
/// except that it does not hold an actual reference. This makes it possible pass
/// around multiple deferred references in unsafe code, without triggering
/// undefined behavior due to existence of aliased mutable references. `Deferred`
/// aims to make it easier to reason about the validity and lifetime of pointers
/// during the act of dereferencing.
/// 
/// # Invariant
/// `Deferred` upholds the same guarantees as its referenceable counter-parts `&T`
/// and `&mut T` (except that it doesn't occupy an actual reference!), it is possible
/// to always dereference it:
/// * The address that `Deferred` points to is guaranteed to be properly aligned.
/// * `Deferred` is guaranteed to be non-dangling.
/// * `Deferred` is guaranteed to be non-null.
/// * `Deferred` is guaranteed to dereference to the same (stack-allocated) object.
/// * The memory that `Deferred` points to is guaranteed to be properly initialized.
/// * `Deferred` is guaranteed to be valid for the duration of its lifetime.
///
/// For mutable pointers, `Deferred<&mut T>` guarantees that no mutable reference(s) existed
/// to (any part of) the `T` instance at the time the `Deferred` was constructed. After
/// a mutable `Deferred<&mut T>` is created, mutable references may be constructed from it
/// (safely or unsafely), but the Rust aliasing rules must always be respected, meaning
/// no two live mutable references may point to overlapping regions in memory, ever.
///
/// # Safety
/// Even though it is possible to work with `Deferred` from purely safe Rust, it also offers
/// additional functionality in `unsafe` code and then the programmer must take special care when
/// dereferencing the `Deferred` or its pointers in unsafe code regarding the usual Rust rules:
/// * Don't create a mutable reference `&mut T` to regions of the memory which already
///   hold an immutable reference `&T` or a mutable reference `&mut T`.
///   The usual Rust aliasing rules still apply, even in unsafe code!
/// * Don't create any reference, `&T` or `&mut T`, to regions of the memory which
///   could be modified from other threads or processes.
/// * Don't create any mutable reference `&mut T` to regions of the memory which
///   could be aliased through a `&T` or `&mut T` from other threads or processes.
/// * Creating immutable aliases `&T` to regions of the memory is fine as long as there
///   are only readers for the same part of the slice, even if it is read from other
///   threads or processes.
#[repr(transparent)] // this is so that it can be casted to and from other pointers
pub struct Deferred<T>
where
    T: Reference,
{
    /// The raw pointer. This pointer may never dangle and must always be valid.
    ptr: NonNull<T::Target>,
}

/// # Constructors for deferred _immutable_ references
/// There exist several ways to construct a deferred immutable reference `Deferred<&T>`, listed here in 
/// order of safety (lower in the list means it's more unsafe).
/// 1. Through the [Deferred::new] method.
/// 2. Through the [From]/[Into] traits implemented for `Deferred<&T>`.
/// 3. Through the [Defer::defer](crate::Defer::defer) method on types that implement the [Defer](crate::Defer) trait.
/// 4. Through the _unsafe_ [Deferred::from_raw] method.
/// 5. Through the _extremely unsafe_ [`defer`](macro@defer) macro (not recommended).
impl<'a, T: ?Sized> Deferred<&'a T> {
    /// Construct a new deferred immutable reference from an existing immutable reference.
    /// ```
    /// use deferred_reference::Deferred;
    /// let x = [1, 2, 3];
    /// let deferred = Deferred::new(&x);
    /// assert_eq!(2, deferred[1]);
    /// ```
    pub fn new(reference: &'a T) -> Self {
        // SAFETY: an actual reference upholds the same guarantees as [Deferred], to this is safe.
        unsafe {
            Self::from_raw(reference)
        }
    }
    /// Construct a new deferred immutable reference to an instance of `T: ?Sized` from a raw pointer.
    /// This method is unsafe. For a safe alternative, use `Deferred::from(&T)` instead. If you don't
    /// have access to a reference or don't want to create one, then this method (`Deferred::from_raw`)
    /// is the method that you could use instead. Alternatively, another safe method is to call the
    /// [Defer::defer](crate::Defer::defer) method on types that implement the [Defer](crate::Defer) trait.
    ///
    /// # Safety
    /// The caller must uphold the invariant of [Deferred], which implies guaranteeing
    /// largely the same safety guarantees as for regular immutable references.
    /// Most importantly this means that the pointer must be derefenceable and may not contain
    /// any part of memory which is left uninitialized. Referencing uninitialized memory of
    /// any type is always instant undefined behavior (see the nomicon at
    /// <https://doc.rust-lang.org/nomicon/uninitialized.html> for more details on this fact).
    /// The caller must also ensure that the pointer remains valid for as long as the returned
    /// `Deferred` exists. If the pointers refers to a shared memory (mapped) region which may
    /// be modified somehow, then it is also the caller's reponsibility never to call safe
    /// methods such as [`<Deferred as Deref>::deref`](core::ops::Deref::deref). This would
    /// alias the entire memory region and is only safe if there are no writers at the same time.
    ///
    /// # Caveat
    /// The lifetime for the returned [Deferred] is inferred from its usage. To prevent accidental misuse,
    /// it's suggested to tie the lifetime to whichever source lifetime is safe in the context, such as
    /// by providing a helper function taking the lifetime of a host value, or by explicit annotation.
    /// ```
    /// use deferred_reference::Deferred;
    /// pub trait MemoryMappedBuffer {
    ///     fn as_ptr(&self) -> *const u8;
    ///     fn len(&self) -> usize;
    /// }
    /// fn defer<'a, T>(buffer: &'a T) -> Deferred<&'a [u8]>
    /// where
    ///     T: MemoryMappedBuffer
    /// {
    ///     let slice_ptr = core::ptr::slice_from_raw_parts(buffer.as_ptr(), buffer.len());
    ///     unsafe { Deferred::from_raw(slice_ptr) }
    /// }
    /// ```
    ///
    /// # Example
    /// ```
    /// use deferred_reference::Deferred;
    /// let buffer = [0u8; 1024];
    /// // SAFETY: `buffer` is not moved or mutably aliased after this.
    /// let deferred = unsafe { Deferred::from_raw(core::ptr::addr_of!(buffer)) };
    /// ```
    pub unsafe fn from_raw(ptr: *const T) -> Self {
        // note: this method must live in the impl for `&'a T`
        // otherwise Rust can't infer the type properly.
        Self {
            // note: the pointer is casted from `*const T` to `*mut T`, but this is safe because
            // this is not undefined behavior. dereferencing the `*mut T` would be UB,
            // but there is no way to do this if it was constructed from a *const T,
            // so this is still sound.
            ptr: NonNull::new_unchecked(ptr as *mut T),
        }
    }
}

/// # Constructors for deferred _mutable_ references
/// There exist several ways to construct a deferred mutable reference `Deferred<&mut T>`, listed here in 
/// order of safety (lower in the list means it's more unsafe).
/// 1. Through the [Deferred::new_mut] method.
/// 2. Through the [From]/[Into] traits implemented for `Deferred<&mut T>`.
/// 3. Through the _unsafe_ [DeferMut::defer_mut](crate::DeferMut::defer_mut) method on types that implement the [DeferMut](crate::DeferMut) trait.
/// 4. Through the _unsafe_ [Deferred::from_raw_mut] method.
/// 5. Through the _extremely unsafe_ [`defer_mut`](macro@defer_mut) macro (not recommended).
impl<'a, T: ?Sized> Deferred<&'a mut T> {
    /// Construct a new deferred mutable reference from an existing mutable reference.
    /// ```
    /// use deferred_reference::Deferred;
    /// let mut x = [1, 2, 3];
    /// let mut deferred = Deferred::new_mut(&mut x);
    /// assert_eq!(&mut 2, &mut deferred[1]);
    /// ```
    pub fn new_mut(reference: &'a mut T) -> Self {
        // SAFETY: an actual reference upholds the same guarantees as [Deferred], to this is safe.
        unsafe {
            Self::from_raw_mut(reference)
        }
    }
    /// Construct a new deferred mutable reference to an instance of `T`.
    ///
    /// # Safety
    /// The caller must uphold the invariant of [Deferred]. Most importantly this means that the pointer must be
    /// derefenceable and may not contain any part of memory which is left uninitialized. Referencing
    /// uninitialized memory of any type is always instant undefined behavior (see the nomicon at
    /// <https://doc.rust-lang.org/nomicon/uninitialized.html> for more details on this fact).
    /// On top of that, the caller must ensure that the pointer remains valid for as long
    /// as the returned `Deferred` exists and that no references to the instance exist when the [Deferred]
    /// is constructed. If the `Deferred` refers to a shared memory (mapped) region which may be modified somehow
    /// (e.g. by other threads or processes), then it is also the caller's reponsibility never to call
    /// the safe methods [`<Deferred as Deref>::deref`](core::ops::Deref::deref) or
    /// [`<Deferred as DerefMut>::deref_mut`](core::ops::DerefMut::deref_mut). This would alias the entire memory
    /// region and is only safe when there are no other writers and readers, respectively.
    ///
    /// # Caveat
    /// The lifetime for the returned `Deferred` is inferred from its usage. To prevent accidental misuse,
    /// it's suggested to tie the lifetime to whichever source lifetime is safe in the context, such as
    /// by providing a helper function taking the lifetime of a host value, or by explicit annotation.
    ///
    /// ```
    /// use deferred_reference::Deferred;
    /// /// SAFETY: `Buffer` may only be implemented on valid smart-pointers which don't own
    /// /// SAFETY: the memory. The smart pointer must also point to fully initialized memory.
    /// pub unsafe trait Buffer {
    ///     fn as_ptr(&self) -> *mut u8;
    ///     fn len(&self) -> usize;
    /// }
    /// /// The lifetime of the returned [Deferred] is bound to the lifetime of the
    /// /// mutable borrow of smart pointer `T` through the explicit lifetime 'a.
    /// fn defer_mut<'a, T>(buffer: &'a mut T) -> Deferred<&'a mut [u8]>
    /// where
    ///     T: Buffer
    /// {
    ///     let slice_ptr = core::ptr::slice_from_raw_parts_mut(buffer.as_ptr(), buffer.len());
    ///     // SAFETY: this is safe because `Deferred` occupies the only mutable reference
    ///     // SAFETY: to the smart pointer `T` for the duration of lifetime 'a, which means
    ///     // SAFETY: no other callers can safely obtain a mutable reference at the same time.
    ///     unsafe { Deferred::from_raw_mut(slice_ptr) }
    /// }
    /// ```
    /// The documentation of [DeferMut](crate::DeferMut) contains some additional examples of how to properly call
    /// [Deferred::from_raw_mut].
    pub unsafe fn from_raw_mut(ptr: *mut T) -> Deferred<&'a mut T> {
        Self {
            ptr: NonNull::new_unchecked(ptr as *mut T),
        }
    }
}

/// # Methods available on all deferred references
impl<T> Deferred<T>
where
    T: Reference,
{
    /// Obtains an immutable pointer to where the deferred reference points.
    /// This pointer can be a thin pointer if `T` is sized or a fat pointer
    /// otherwise.
    pub fn as_ptr(&self) -> *const T::Target {
        self.ptr.as_ptr() as *const _
    }

    /// Unsizes the deferred reference. This method is experimental.
    ///
    /// # Example
    /// ```
    /// use deferred_reference::{Defer, DeferMut, Deferred};
    /// use core::cell::UnsafeCell;
    /// let mut buffer = UnsafeCell::new([0u8; 1024]);
    /// let deferred_array /* : Deferred<&[u8; 1024]> */ = buffer.defer();
    /// let deferred_slice: Deferred<&[u8]> = deferred_array.unsize(); // needs an explicit type
    /// let deferred_array_mut /* : Deferred<&mut [u8; 1024]> */ = unsafe { buffer.defer_mut() };
    /// let deferred_slice_mut: Deferred<&mut [u8]> = deferred_array_mut.unsize();
    /// ```
    ///
    /// # Unstable
    /// This method requires the unstable `Cargo.toml` feature `unstable` or `coerce_unsized` to be enabled.
    /// This method may become stable once the `coerce_unsized` feature lands in stable Rust, see
    /// <https://github.com/rust-lang/rust/issues/27732>. For a stable alternative, you may also use
    /// use the [From]/[Into] traits which are implemented on [Deferred] for converting deferred arrays to
    /// deferred slices.
    #[cfg(feature = "coerce_unsized")]
    pub fn unsize<U>(self) -> Deferred<U>
    where
        U: Reference,
        NonNull<T::Target>: core::ops::CoerceUnsized<NonNull<U::Target>>, // requires #![feature(coerce_unsized)]`
    {
        Deferred {
            ptr: self.ptr,
        }
    }
}

/// # Methods available for all deferred _mutable_ references
impl<'a, T: ?Sized> Deferred<&'a mut T> {
    /// Obtains an mutable pointer to where the deferred reference points.
    /// This pointer can be a thin pointer if `T` is sized or a fat pointer
    /// otherwise.
    pub fn as_mut_ptr(&self) -> *mut T {
        self.ptr.as_ptr()
    }
    /// Make a copy of this mutable `Deferred<&'a mut T>`. The copy will have the same lifetime as `'a`.
    ///
    /// # Safety
    /// This method can be very unsafe. Cloning a mutable deferred reference will let you safely dereference it mutably
    /// afterwards (e.g. through [`<Deferred<&mut T> as DerefMut>::deref_mut`](core::ops::DerefMut::deref_mut)) from several
    /// distinct places simultaneously and this could lead to aliased mutable references which is then instant undefined behavior.
    /// That is why this function is marked as unsafe. Cloning a `Deferred<&mut T>` is not undefined behavior, because this is a
    /// smart pointer and not an actual live reference. Be very careful not to accidentally create mutable aliased references through
    /// dereferencing any `Deferred<&mut T>` after calling [`Deferred::clone_unchecked`](Deferred::clone_unchecked) on it!!!
    /// Calling [`<Deferred as Clone>::clone`](Clone::clone) on immutable deferred references (i.e. `Deferred<&T>`) is entirely safe
    /// (and all `Deferred<&T>` also implement the [Copy] trait).
    pub unsafe fn clone_unchecked(&self) -> Self {
        // SAFETY: calling `from_raw_parts_mut` is safe because the invariant of [Deferred] is respected.
        // SAFETY: still this method is unsafe by itself, see the Safety notes.
        Deferred::from_raw_mut(self.as_mut_ptr())
    }
    /// Convert this deferred mutable reference into a deferred immutable reference.
    ///
    /// # Example
    /// ```
    /// use deferred_reference::{DeferMut, Deferred};
    /// use core::cell::UnsafeCell;
    /// let buffer = UnsafeCell::new([0u8; 1024]);
    /// // SAFETY: this is safe, because this is the only deferred reference we create:
    /// let deferred_mut: Deferred<&mut [u8; 1024]> = unsafe { buffer.defer_mut() };
    /// // which we then convert into a deferred immutable reference:
    /// let deferred: Deferred<&[u8; 1024]> = deferred_mut.into_ref();
    /// ```
    pub fn into_ref(self) -> Deferred<&'a T> {
        self.into()
    }
}

#[cfg(test)]
mod tests {
    use core::cell::UnsafeCell;
    use crate::{Defer, DeferMut, Deferred};

    #[test]
    fn new() {
        let mut buffer = [0u8; 1024];
        let mut deferred = Deferred::from(&mut buffer);
        //assert_eq!(0, buffer[0]); // cannot borrow `buffer[_]` as immutable because it is also borrowed as mutable
        assert_eq!(0, deferred[0]);
        assert_eq!(&mut 0, &mut deferred[0]);
        let mut deferred2 = unsafe { deferred.clone_unchecked() };
        let tmp1: &mut [u8] = &mut deferred[10..20];
        // let tmp2 = &mut deferred2[30..40];
        tmp1[0] = 42; // UB because `tmp2` creates a new &mut reference
        // tmp2[0] = 42;
        // assert_eq!(&mut tmp1[0], &mut tmp2[0]);
        deferred2[0] = 42;
        assert_eq!(42, deferred[0]);
        assert_eq!(42, buffer[0]);
    }

    #[test]
    fn mut_ref_invalidation() {
        let buffer = UnsafeCell::new([0u8; 1024]);
        let mut deferred = unsafe { buffer.defer_mut() };
        let mut deferred2 = unsafe { deferred.clone_unchecked() };
        deferred[10] = 1; // not UB, because mutable reference is temporary
        deferred2[30] = 1; // not UB, because new mutable reference is created
        let _tmp1 = &mut deferred[10..20];
        let tmp2 = &mut deferred2[30..40];
        // tmp1[0] = 42; // UB because `tmp2` creates a new &mut reference
        tmp2[0] = 42;
        // assert_eq!(&mut tmp1[0], &mut tmp2[0]); // UB
    }

    /// Tests whether [Deferred] can be casted to pointers of other types without UB
    #[test]
    fn cast_to_ptr() {
        let mut buffer = UnsafeCell::new([0u8; 1024]);
        buffer.get_mut()[0] = 1;
        {
            let deferred = buffer.defer();
            let ptr = unsafe { *(core::ptr::addr_of!(deferred) as *const *const [u8; 1024]) };
            assert_eq!(*deferred, unsafe { *ptr });
        }
        {
            let deferred = unsafe { buffer.defer_mut() };
            let ptr = unsafe { *(core::ptr::addr_of!(deferred) as *const *mut [u8; 1024]) };
            assert_eq!(*deferred, unsafe { *ptr });
        }
        {
            let mut deferred = unsafe { buffer.defer_mut() };
            let ptr = unsafe { *(core::ptr::addr_of_mut!(deferred) as *mut *mut [u8; 1024]) };
            assert_eq!(*deferred, unsafe { *ptr });
        }
    }

    /// Tests that niche size optimization works.
    #[test]
    fn size_of() {
        assert_eq!(core::mem::size_of::<Deferred<&[u8]>>(), core::mem::size_of::<Option<Deferred<&[u8]>>>())
    }

    /// Tests that pointers point to the same address.
    #[test]
    fn as_ptr() {
        let buffer = UnsafeCell::new([0u8; 1024]);
        let deferred = buffer.defer();
        assert_eq!(deferred.as_ptr() as usize, buffer.get() as usize);
    }

    /// Tests that mutable pointers point to the same address.
    #[test]
    fn as_mut_ptr() {
        let buffer = UnsafeCell::new([0u8; 1024]);
        let deferred = unsafe { buffer.defer_mut() };
        assert_eq!(deferred.as_mut_ptr() as usize, buffer.get() as usize);
    }

    
}