deferred-reference 0.1.2

A deferred reference is not an actual reference, it is merely a smart pointer tied to the lifetime of the location it points to.
Documentation
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
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
use core::cell::UnsafeCell;

use super::{Defer, Deferred};

/// An unsafe macro to create a deferred mutable reference (i.e. a [`Deferred<&mut T>`](Deferred)) to a place,
/// without creating an intermediate reference. See the documentation at [Deferred] explaining the
/// [constructors for deferred mutable references](Deferred#constructors-for-deferred-mutable-references)
/// for safer alternatives.
///
/// Use of this macro is not recommended, because it's a lot more unsafe than obtaining a `Deferred<&mut T>` through
/// a type that implements the [DeferMut] trait. Use [`DeferMut::defer_mut`](DeferMut::defer_mut) or
/// [`Deferred::from(&mut T)`](From::from) for a safer alternative instead.
///
/// The only use case for this macro is when you can't create a reference to a place and also can't use [UnsafeCell]
/// to achieve interior mutability. However, this is a rare case and requires advanced knowledge of unsafe Rust.
///
/// # Example
/// ```
/// #[macro_use]
/// extern crate deferred_reference;
/// use deferred_reference::Deferred;
/// fn main() {
///     let mut buffer = [0u8; 1024];
///     let deferred: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
///     assert_eq!(buffer[0], deferred[0]);
///     // works also for references to arrays:
///     let deferred: Deferred<&mut [u8; 1024]> =  unsafe { defer_mut!(buffer) };
///     assert_eq!(buffer[0], deferred[0]);
/// }
/// ```
///
/// # Safety
/// This macro is very unsafe and should only be used if there is no other safe way to obtain a deferred mutable reference.
/// See the [DeferMut] trait for the preferred way to create an deferred mutable reference. When using this
/// macro, the caller must uphold the following guarantees:
/// * When dereferencing the [Deferred], the Rust alias rules must be upheld at all times. E.g. don't create mutable and
///   immutable references to the same place (these may not partially overlap either).
/// * The place must be properly aligned and initialized.
/// * The caller must ensure that the invariant of the returned [Deferred] is upheld.
/// * The place must not be moved or dropped for as long as the returned [Deferred] is in use.
/// * No explicit references to the place may be created as long as the [Deferred] is in use. This will invalidate the [Deferred].
/// * Any other instances of [Deferred] that point to the same location, must be reborrowed from the original deferred mutable reference.
///   This is possible using [Deferred::clone_unchecked] and [Deferred::into_ref]. Any other deferred references will becomed invalidated
///   as soon as the deferred mutable reference is dereferenced (unless its target contents are inside an [UnsafeCell]).
///
/// Here is an example that will trigger undefined behavior, in order to illustrate how unsafe this macro is:
/// ```no_run
/// #[macro_use]
/// extern crate deferred_reference;
/// fn main() {
///     let mut buffer = [0u8; 1024];
///     let deferred = unsafe { defer_mut!(buffer) };
///     buffer[0] = 42; // implicitly creates a temporary mutable reference to all of `buffer`
///     // `deferred` is now invalidated !!!
///     // therefore dereferencing `deferred` is undefined behavior, even though
///     // the lifetimes of the immutable and mutable references don't overlap:
///     assert_eq!(buffer[0], deferred[0]); // undefined behavior!!!
/// }
/// ```
///
/// # 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.
/// However, this can get very complicated and very unsafe real fast, see the [`defer`](macro@defer#caveat)
/// macro for an example of how to do this without creating an intermediate reference.
///
/// # How can this be safely used together with the `defer!` macro?
/// As mentioned above under section "[*Safety*](#safety)", dereferencing a `Deferred<&mut T>` will invalidate any other [Deferred] instances 
/// which are not re-borrowed, even the ones created by the [`defer`](macro@defer) macro (`Deferred<&T>` instances returned by the
/// [`defer`](macro@defer) macro do not constitute as re-borrows). This means that the [`defer`](macro@defer) macro is only safe to use
/// together with the [`defer_mut`](macro@defer_mut) macro if you take special care to always call [`defer!`](macro@defer) again to refresh
/// its pointer, after a mutable reference has been given out through dereferencing the `Deferred<&mut T>.` For example, this is definately
/// __considered undefined behavior__:
/// ```no_run
/// #[macro_use]
/// extern crate deferred_reference;
/// use deferred_reference::Deferred;
/// fn main() {
///     let mut buffer = [0u8; 1024];
///     // SAFETY: what we are about to do is very unsafe!
///     let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
///     let deferred: Deferred<&[u8]> =  unsafe { defer!(buffer) };
///     assert_eq!(0, deferred_mut[0]);
///     assert_eq!(0, deferred[0]); // so far so good, no UB yet...
///     deferred_mut[0] = 42; // this implicity creates a mutable reference to `buffer`
///     // `deferred` is now invalidated!
///     assert_eq!(42, deferred_mut[0]); // this is not yet UB...
///     assert_eq!(42, deferred[0]); // this is UB!
/// }
/// ```
/// The undefined behavior can be side-stepped if the deferred mutable reference is re-borrowed, like so:
/// ```
/// #[macro_use]
/// extern crate deferred_reference;
/// use deferred_reference::Deferred;
/// fn main() {
///     let mut buffer = [0u8; 1024];
///     // SAFETY: this is safe because we reborrow `deferred_mut` and
///     // SAFETY: we don't create any overlapping references.
///     let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
///     let deferred: Deferred<&[u8]> = unsafe { deferred_mut.clone_unchecked().into_ref() };
///     assert_eq!(0, deferred_mut[0]);
///     assert_eq!(0, deferred[0]);
///     deferred_mut[0] = 42; // this implicity creates a mutable reference to `buffer`
///     assert_eq!(42, deferred_mut[0]);
///     assert_eq!(42, deferred[0]); // but this is not UB thanks the re-borrow
/// }
/// ```
/// If the calls to the [`defer`](macro@defer) macro are timed well, then it is possible to combine
/// the two macros without running into undefined behavior:
/// ```
/// #[macro_use]
/// extern crate deferred_reference;
/// use deferred_reference::Deferred;
/// fn main() {
///     let mut buffer = [0u8; 1024];
///     // SAFETY: this is safe, because we create new deferred references after
///     // SAFETY: dereferencing `deferred_mut` into an actual mutable reference.
///     let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
///     let mut deferred: Deferred<&[u8]> = unsafe { defer!(buffer) };
///     assert_eq!(0, deferred_mut[0]);
///     assert_eq!(0, deferred[0]);
///     deferred_mut[0] = 42; // this implicity creates a temporary mutable reference to `buffer`
///     // `deferred` is now invalidated! we refresh it again:
///     deferred = unsafe { defer!(buffer) };
///     assert_eq!(42, deferred_mut[0]);
///     // this is not UB, because the mutable reference did not overlap
///     // with the re-creation of `deferred`:
///     assert_eq!(42, deferred[0]); 
/// }
/// ```
/// The previous 3 examples consist of very unsafe Rust and should not be attempted unless there
/// exists a specific reason why this is needed and the implementor has intricate knowledge
/// about raw pointer management in Rust. In all other cases, using the [DeferMut::defer_mut]
/// is the much better alternative to the [`defer_mut`](macro@defer_mut) macro.
#[macro_export]
macro_rules! defer_mut {
    ($place:expr) => {
        $crate::Deferred::from_raw_mut(core::ptr::addr_of_mut!($place))
    };
}

/// The [DeferMut] trait offers easy access to deferred mutable references
/// to types that implement [DeferMut]. This trait is already implemented on all types `T: ?Sized` for
/// [`UnsafeCell<T>`](core::cell::UnsafeCell) out-of-the-box and this should be sufficient for most purposes,
/// but it is also possible to implement the [Defer] and [DeferMut] traits for your own types, please see
/// the documentation of this trait on how to do this safely.
/// 
/// # Safety
/// This trait may only be implemented for:
/// 1. All types that support interior mutability. Concretely, this means that
/// for types that have interior mutability, the type must contain an [UnsafeCell] or one of
/// of its derivatives, such as those in the Rust standard library like `RefCell`, `RwLock` or `Mutex`.
/// 2. Other smart-pointers which do not "own" their data. Smart-pointers which contain a
/// mutable pointer `*mut T` don't need to wrap the mutable pointer in an [UnsafeCell], because
/// dereferencing a mutable pointer does not constitute interior mutability.
///
/// Additionally, all types that implement [DeferMut] must uphold the following invariants:
/// * The type must also implement the [Defer] trait.
/// * The deferred reference that the [DeferMut::defer_mut] method returns, must point to the same location
///   as the [Deferred] returned by [Defer::defer].
/// * Both the [Defer] and [DeferMut] trait implementations may not create any references
///   to the location where the returned [Deferred] points, nor may the location
///   be accessed in any way (e.g. dereferencing). Taking an immutable shared reference to a wrapping [UnsafeCell]
///   is okay, but creating a reference to the contents of the [UnsafeCell] is not! Creating a
///   mutable reference to the wrapping [UnsafeCell] is also not okay, because [UnsafeCell] only protects
///   shared references to a place that may be mutated, it does not weaken the rules for mutable references,
///   which say that a mutable reference must be exclusive in order to stay clear of undefined behavior.
///
/// # Example
/// Here is an example for how to implement this trait for custom smart pointers.
/// ```
/// use deferred_reference::{Defer, DeferMut, Deferred};
/// /// `MemoryMappedBuffer` is a simplified representation of a memory mapped slice of bytes.
/// /// Proper implementations would also contain a `MemoryMappedBuffer::new` constructor
/// /// which sets up the owned memory map and `MemoryMappedBuffer` should also implement
/// /// the `Drop` trait to properly clean up the memory map when `MemoryMappedBuffer`
/// /// goes out of scope.
/// pub struct MemoryMappedBuffer {
///     ptr: *mut u8,
///     length: usize,
/// }
/// impl Defer for MemoryMappedBuffer {
///     type Target = [u8];
///     fn defer(&self) -> Deferred<&[u8]> {
///         let slice_ptr = core::ptr::slice_from_raw_parts(self.ptr as *const u8, self.length);
///         // SAFETY: this is safe because the Deferred occupies a shared reference to the
///         // SAFETY: smart pointer `MemoryMappedBuffer` for the duration of lifetime of &self,
///         // SAFETY: which means no other callers can safely obtain a mutable reference
///         // SAFETY: the MemoryMappedBuffer instance.
///         unsafe { Deferred::from_raw(slice_ptr) }
///     }
/// }
/// // SAFETY: this is safe, because the invariant of `Deferred` is upheld.
/// // SAFETY: this is only safe if the memory mapped region is properly aligned and initialized
/// // SAFETY: and `ptr` is non-null and not dangling (i.e. it must point to a valid memory region).
/// unsafe impl DeferMut for MemoryMappedBuffer {
///     unsafe fn defer_mut(&self) -> Deferred<&mut [u8]> {
///         let slice_mut_ptr = core::ptr::slice_from_raw_parts_mut(self.ptr, self.length);
///         Deferred::from_raw_mut(slice_mut_ptr)
///     }
/// }
/// ```
/// If you want to build your own custom smart pointer that also owns the backing memory,
/// then you can use `Vec`, `Box` and `UnsafeCell` to do so through interior mutability like this:
/// ```
/// use deferred_reference::{Defer, DeferMut, Deferred};
/// use core::ops::{Deref, DerefMut};
/// use core::cell::UnsafeCell;
/// pub struct MyBuffer {
///     memory: Box<UnsafeCell<[u8]>>,
/// }
/// impl MyBuffer {
///     fn new(capacity: usize) -> Self {
///         let mut vector = Vec::with_capacity(capacity);
///         // we have to initialize the full vector, otherwise it is undefined behavior
///         // when we give out references to the backing slice of bytes.
///         vector.resize(capacity, 0u8);
///         let boxed_slice: Box<[u8]> = vector.into_boxed_slice();
///         // SAFETY: UnsafeCell is #[repr(transparent)] so this is safe.
///         let memory: Box<UnsafeCell<[u8]>> = unsafe { core::mem::transmute(boxed_slice) };
///         Self { memory }
///     }
/// }
/// // we only need to implement Deref, because the Defer and DeferMut
/// // traits are already implemented for UnsafeCell<[u8]>.
/// impl Deref for MyBuffer {
///     type Target = UnsafeCell<[u8]>;
///     fn deref(&self) -> &Self::Target {
///         self.memory.deref()
///     }
/// }
/// // we also implement DerefMut just to illustrate the invalidation of
/// // Deferred when taking out a mutable borrow. this is optional.
/// impl DerefMut for MyBuffer {
///     fn deref_mut(&mut self) -> &mut Self::Target {
///         self.memory.deref_mut()
///     }
/// }
/// fn main() {
///     let mut my_buffer = MyBuffer::new(1024 * 100); // 100kb buffer
///     // SAFETY: this is safe, because there exist no references to the slice.
///     let deferred_mut: Deferred<&mut [u8]> = unsafe { my_buffer.defer_mut() };
///     // the next line implicitly calls Deref::deref() on `my_buffer`.
///     // this is also okay, because the slice sits inside an UnsafeCell.
///     let deferred: Deferred<&[u8]> = my_buffer.defer();
///     // the next statement is also safe, because by taking out a `&mut self` on MyBuffer
///     // the deferred references are invalidated due to their lifetimes.
///     // this implicitly calls DerefMut::deref_mut() and then UnsafeCell::get_mut():
///     let mut_ref: &mut [u8] = my_buffer.get_mut();
///     // with the next statement uncommmented, the above statement will error:
///     // "cannot borrow `my_buffer` as mutable because it is also borrowed as immutable"
///     //let mut_ref2: &mut [u8] = deferred_mut.deref_mut(); // uncomment for error
/// }
/// ```
pub unsafe trait DeferMut: Defer {
    /// Obtain a deferred mutable reference to [Defer::Target].
    /// 
    /// # Example
    /// ```
    /// use deferred_reference::{Defer, DeferMut};
    /// use core::cell::UnsafeCell;
    /// let buffer = UnsafeCell::new([0u8; 1024]);
    /// // calling defer() or defer_mut() immutably borrows `buffer` for as long
    /// // as the returned `Deferred` is in use.
    /// let deferred = buffer.defer();
    /// // SAFETY: this is safe, because we promise not to create an overlapping mutable reference
    /// let mut deferred_mut = unsafe { buffer.defer_mut() };
    /// // both `deferred` and `deferred_mut` can be safely immutably dereferenced simultaneously:
    /// assert_eq!(&deferred[0], &deferred_mut[0]);
    /// // we can mutate the `buffer` through `deferred_mut` as any other array.
    /// // this implicity creates a temporary mutable reference into the array inside `buffer`.
    /// // even though an immutable reference to `buffer` exists, this is okay because
    /// // the inner array sits inside an `UnsafeCell` which allows interior mutability:
    /// deferred_mut[0] = 42; 
    /// // and observe the change through `deferred`:
    /// assert_eq!(deferred[0], 42);
    /// // all this time, both deferred references are alive, but because
    /// // these are not actual references, this doesn't violate the Rust borrow
    /// // rules and this is not undefined behavior. The lifetimes of the mutable
    /// // and immutable references derived from the Deferred do not overlap,
    /// // so the Rust borrow rules are respected all this time.
    /// assert_eq!(&deferred[0], &deferred_mut[0]);
    /// // this also works for multiple deferred mutable references!
    /// // SAFETY: this is safe, because we promise not to create overlapping references
    /// let mut deferred_mut2 = unsafe { buffer.defer_mut() };
    /// // we can mutate the buffer through 2 distinct deferred mutable references
    /// // (as long as we don't do this at the same time!)
    /// deferred_mut[0] += 1;
    /// deferred_mut2[0] += 1;
    /// assert_eq!(44, deferred[0]);
    /// assert_eq!(deferred_mut[0], deferred_mut2[0]);
    /// // because `Deferred` implements the `Index` and `IndexMut` trait, it is possible
    /// // to create two references that overlap in lifetime, but are disjoint in index:
    /// assert_eq!(&mut deferred_mut[1], &mut deferred_mut2[2]); // indices are disjoint, so no UB
    /// ```
    ///
    /// # Safety
    /// This method is unsafe, because it is possible to call it more than once. This is in contrast
    /// to the regular Rust borrowing rules, where it is only allowed to have one mutable borrow at
    /// a time. [Deferred] instances are not actual references and this is why this is not considered
    /// undefined behavior. However, the absence of instant undefined behavior does not make this
    /// method safe. [Deferred] also implements the [DerefMut](core::ops::DerefMut) trait, which lets
    /// anyone call `<Deferred as DerefMut>::deref_mut(&mut self)` on the [Deferred] and this creates
    /// an actual mutable reference from safe code. Hence, this method must be marked as unsafe,
    /// otherwise it could lead to unsoundness when creating multiple mutable references from safe code.
    /// The caller must take special care not to create any references (mutable or immutable) that
    /// may overlap with the actual mutable reference created from the returned [`Deferred<&mut T>`](Deferred).
    /// Note that overlap means a reference to the same region during the same lifetime. If two
    /// [Deferred] both create a reference to the same region, but with disjoint lifetimes, then
    /// this is safe.
    unsafe fn defer_mut(&self) -> Deferred<&mut Self::Target>;
}

unsafe impl<T: ?Sized> DeferMut for UnsafeCell<T> {
    unsafe fn defer_mut(&self) -> Deferred<&mut T> {
        Deferred::from_raw_mut(self.get())
    }
}

unsafe impl<T: ?Sized> DeferMut for Deferred<&mut T> {
    unsafe fn defer_mut(&self) -> Deferred<&mut Self::Target> {
        Deferred::from_raw_mut(self.as_mut_ptr())
    }
}

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

    /// this test is identical to the example doctest of [DeferMut],
    /// but it is repeated here because Miri does not support doctests yet.
    #[test]
    fn doc_test() {
        let buffer = UnsafeCell::new([0u8; 1024]);
        // calling defer() or defer_mut() immutably borrows `buffer` for as long
        // as the returned `Deferred` is in use.
        let deferred = buffer.defer();
        // SAFETY: this is safe, because we promise not to create overlapping references
        let mut deferred_mut = unsafe { buffer.defer_mut() };
        // both `deferred` and `deferred_mut` can be safely immutably dereferenced:
        assert_eq!(&deferred[0], &deferred_mut[0]);
        // we can mutate the `buffer` through `deferred_mut` as any other array.
        // this implicity creates a temporary mutable reference into the array inside `buffer`.
        // even though an immutable reference to `buffer` exists, this is okay because
        // the inner array sits inside an `UnsafeCell` which allows interior mutability:
        deferred_mut[0] = 42;
        // and observe the change through `deferred`:
        assert_eq!(deferred[0], 42);
        // all this time, both deferred references are alive, but because
        // these are not actual references, this doesn't violate the Rust borrow
        // rules and this is not undefined behavior. The lifetimes of the mutable
        // and immutable references derived from the Deferred do not overlap,
        // so the Rust borrow rules are respected all this time.
        assert_eq!(&deferred[0], &deferred_mut[0]);
        // this also works for multiple deferred mutable references!
        // SAFETY: this is safe, because we promise not to create overlapping references
        let mut deferred_mut2 = unsafe { buffer.defer_mut() };
        // we can mutate the buffer through 2 distinct deferred mutable references
        // (as long as we don't do this at the same time!)
        deferred_mut[0] += 1;
        deferred_mut2[0] += 1;
        assert_eq!(44, deferred[0]);
        assert_eq!(deferred_mut[0], deferred_mut2[0]);
        // however, the following is not okay, because this would create two overlapping
        // mutable references and this is undefined behavior (hence the use of `unsafe` above):
        //assert_eq!(&mut deferred_mut[0], &mut deferred_mut2[0]);
        // because `Deferred` implements the `Index` and `IndexMut` trait, it is possible
        // to create two references that overlap in lifetime, but are disjoint in index:
        assert_eq!(&mut deferred_mut[1], &mut deferred_mut2[2]); // indices are disjoint, so no UB
    }

    mod defer_mut_macro {
        use crate::{defer, Deferred};
        #[test]
        fn call_macro() {
            let mut buffer = [1u8; 1024];
            let mut deferred = unsafe { defer_mut!(buffer) };
            assert_eq!(buffer[0], deferred[0]);
            deferred[0] = 2;
            assert_eq!(2, buffer[0]);
        }
        // /// this triggers UB in miri, because deferred gets invalidated
        // #[test]
        // fn example_ub() {
        //     let mut buffer = [2u8; 1024];
        //     let deferred = unsafe { defer_mut!(buffer) };
        //     // this is undefined behavior:
        //     buffer[0] = 42; // because this implicitly creates a temporary mutable reference
        //     assert_eq!(buffer[0], deferred[0]);
        // }
        
        #[test]
        fn assert_no_reference_created() {
            let mut buffer = [3u8; 1024];
            let mut deferred = unsafe { defer_mut!(buffer) };
            assert_eq!(&3, &buffer[0]); // this implicitly creates a temporary immutable reference to all of `buffer`
            // this is undefined behavior:
            //buffer[0] = 42; // because this implicitly creates a temporary mutable reference to all of `buffer`, which invalidates `deferred`
            // but this is not undefined behavior:
            deferred[0] = 42; // because the mutable pointer to `buffer` inside `deferred` is re-borrowed
            assert_eq!(buffer[0], deferred[0]);
            assert_eq!(42, buffer[0]);
        }

        /// extra test to ensure the doctest above doesn't cause UB (miri doesn't work on doctests yet)
        #[test]
        fn doc_test() {
            let mut buffer = [0u8; 1024];
            let deferred: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
            assert_eq!(buffer[0], deferred[0]);
            // works also for references to arrays:
            let deferred: Deferred<&mut [u8; 1024]> =  unsafe { defer_mut!(buffer) };
            assert_eq!(buffer[0], deferred[0]);
        }

        /// canary test to see if mutable references reborrowed from Deferred invalidate other Deferred.
        /// (so far miri doesn't complain here yet)
        #[test]
        fn overlapping_deferreds() {
            let mut buffer = [3u8; 1024];
            let mut deferred1 = unsafe { defer_mut!(buffer) };
            let mut deferred2 = unsafe { defer_mut!(buffer) };
            assert_eq!(&mut 3, &mut deferred1[0]);
            assert_eq!(&mut 3, &mut deferred2[0]);
            assert_eq!(&mut 3, &mut deferred1[0]);
            deferred1[0] = 42;
            deferred2[1] = 42;
            assert_eq!(&mut 42, &mut deferred2[0]);
            assert_eq!(&mut 42, &mut deferred1[0]);
            assert_eq!(&mut 42, &mut deferred2[0]);
            assert_eq!(&deferred1[..], &deferred2[..]);
        }

        #[test]
        fn mixing_defer_and_defer_mut() {
            let mut buffer = [0u8; 1024];
            let deferred: Deferred<&[u8]> =  unsafe { crate::defer!(buffer) };
            assert_eq!(0, deferred[0]);
            let mut deferred_mut: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
            assert_eq!(0, deferred[0]); // deferred is still valid
            deferred_mut[0] = 42;
            assert_eq!(42, deferred_mut[0]);
            // the previous line created a mutable reference, so we need to re-obtain Deferred<&[u8]>
            let deferred: Deferred<&[u8]> =  unsafe { crate::defer!(buffer) }; // omitting this line is UB!
            assert_eq!(42, deferred[0]);
            assert_eq!(42, deferred_mut[0]);
        }
        #[test]
        fn mixing_defer_and_defer_mut2() {
            let mut buffer = [0u8; 1024];
            let mut deferred_mut: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
            assert_eq!(0, deferred_mut[0]);
            let deferred: Deferred<&[u8]> =  unsafe { crate::defer!(buffer) };
            assert_eq!(0, deferred[0]);
            deferred_mut[0] = 42;
            assert_eq!(42, deferred_mut[0]);
            // the previous line created a mutable reference, so we need to re-obtain Deferred<&[u8]>
            let deferred: Deferred<&[u8]> =  unsafe { crate::defer!(buffer) }; // omitting this line is UB!
            assert_eq!(42, deferred[0]);
            assert_eq!(42, deferred_mut[0]);
        }
        #[test]
        fn mixing_defer_and_defer_mut3() {
            let mut buffer = [0u8; 1024];
            let mut deferred_mut: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
            assert_eq!(0, deferred_mut[0]);
            // here we create a deferred immutable reference which reborrows the pointer:
            let deferred: Deferred<&[u8]> = unsafe { deferred_mut.clone_unchecked().into() };   
            assert_eq!(0, deferred[0]);
            deferred_mut[0] = 42;
            assert_eq!(42, deferred[0]); // NOT UB! thanks to the reborrow
            assert_eq!(42, deferred_mut[0]);
        }

        #[test]
        fn doctest_defer1() {
            let mut buffer = [0u8; 1024];
            // SAFETY: what we are about to do is very unsafe!
            let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
            let deferred: Deferred<&[u8]> =  unsafe { defer!(buffer) };
            assert_eq!(0, deferred_mut[0]);
            assert_eq!(0, deferred[0]); // so far so good, no UB yet...
            deferred_mut[0] = 42; // this implicity creates a mutable reference to `buffer`
            // `deferred` is now invalidated!
            assert_eq!(42, deferred_mut[0]);
            //assert_eq!(42, deferred[0]); // this is UB!
        }
        #[test]
        fn doctest_defer2() {
            let mut buffer = [0u8; 1024];
            // SAFETY: this is safe because we reborrow `deferred_mut` and
            // SAFETY: we don't create any overlapping references.
            let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
            let deferred: Deferred<&[u8]> = unsafe { deferred_mut.clone_unchecked().into_ref() };
            assert_eq!(0, deferred_mut[0]);
            assert_eq!(0, deferred[0]);
            deferred_mut[0] = 42; // this implicity creates a mutable reference to `buffer`
            assert_eq!(42, deferred_mut[0]);
            assert_eq!(42, deferred[0]); // but this is not UB thanks the re-borrow
        }
        #[test]
        fn doctest_defer3() {
            let mut buffer = [0u8; 1024];
            // SAFETY: this is safe, because we create new deferred references after
            // SAFETY: dereferencing `deferred_mut` into an actual mutable reference.
            let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
            let mut deferred: Deferred<&[u8]> = unsafe { defer!(buffer) };
            assert_eq!(0, deferred_mut[0]);
            assert_eq!(0, deferred[0]); // so far so good, no UB yet...
            deferred_mut[0] = 42; // this implicity creates a temporary mutable reference to `buffer`
            // `deferred` is now invalidated! we refresh it again:
            deferred = unsafe { defer!(buffer) };
            assert_eq!(42, deferred_mut[0]);
            // this is not UB, because the mutable reference did not overlap
            // with the re-creation of `deferred`:
            assert_eq!(42, deferred[0]); 
        }
    }
}