deferred_reference/
defer_mut.rs

1use core::cell::UnsafeCell;
2
3use super::{Defer, Deferred};
4
5/// An unsafe macro to create a deferred mutable reference (i.e. a [`Deferred<&mut T>`](Deferred)) to a place,
6/// without creating an intermediate reference. See the documentation at [Deferred] explaining the
7/// [constructors for deferred mutable references](Deferred#constructors-for-deferred-mutable-references)
8/// for safer alternatives.
9///
10/// Use of this macro is not recommended, because it's a lot more unsafe than obtaining a `Deferred<&mut T>` through
11/// a type that implements the [DeferMut] trait. Use [`DeferMut::defer_mut`](DeferMut::defer_mut) or
12/// [`Deferred::from(&mut T)`](From::from) for a safer alternative instead.
13///
14/// The only use case for this macro is when you can't create a reference to a place and also can't use [UnsafeCell]
15/// to achieve interior mutability. However, this is a rare case and requires advanced knowledge of unsafe Rust.
16///
17/// # Example
18/// ```
19/// #[macro_use]
20/// extern crate deferred_reference;
21/// use deferred_reference::Deferred;
22/// fn main() {
23///     let mut buffer = [0u8; 1024];
24///     let deferred: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
25///     assert_eq!(buffer[0], deferred[0]);
26///     // works also for references to arrays:
27///     let deferred: Deferred<&mut [u8; 1024]> =  unsafe { defer_mut!(buffer) };
28///     assert_eq!(buffer[0], deferred[0]);
29/// }
30/// ```
31///
32/// # Safety
33/// This macro is very unsafe and should only be used if there is no other safe way to obtain a deferred mutable reference.
34/// See the [DeferMut] trait for the preferred way to create an deferred mutable reference. When using this
35/// macro, the caller must uphold the following guarantees:
36/// * When dereferencing the [Deferred], the Rust alias rules must be upheld at all times. E.g. don't create mutable and
37///   immutable references to the same place (these may not partially overlap either).
38/// * The place must be properly aligned and initialized.
39/// * The caller must ensure that the invariant of the returned [Deferred] is upheld.
40/// * The place must not be moved or dropped for as long as the returned [Deferred] is in use.
41/// * No explicit references to the place may be created as long as the [Deferred] is in use. This will invalidate the [Deferred].
42/// * Any other instances of [Deferred] that point to the same location, must be reborrowed from the original deferred mutable reference.
43///   This is possible using [Deferred::clone_unchecked] and [Deferred::into_ref]. Any other deferred references will becomed invalidated
44///   as soon as the deferred mutable reference is dereferenced (unless its target contents are inside an [UnsafeCell]).
45///
46/// Here is an example that will trigger undefined behavior, in order to illustrate how unsafe this macro is:
47/// ```no_run
48/// #[macro_use]
49/// extern crate deferred_reference;
50/// fn main() {
51///     let mut buffer = [0u8; 1024];
52///     let deferred = unsafe { defer_mut!(buffer) };
53///     buffer[0] = 42; // implicitly creates a temporary mutable reference to all of `buffer`
54///     // `deferred` is now invalidated !!!
55///     // therefore dereferencing `deferred` is undefined behavior, even though
56///     // the lifetimes of the immutable and mutable references don't overlap:
57///     assert_eq!(buffer[0], deferred[0]); // undefined behavior!!!
58/// }
59/// ```
60///
61/// # Caveat
62/// The lifetime for the returned [Deferred] is inferred from its usage. To prevent accidental misuse,
63/// it's suggested to tie the lifetime to whichever source lifetime is safe in the context, such as
64/// by providing a helper function taking the lifetime of a host value, or by explicit annotation.
65/// However, this can get very complicated and very unsafe real fast, see the [`defer`](macro@defer#caveat)
66/// macro for an example of how to do this without creating an intermediate reference.
67///
68/// # How can this be safely used together with the `defer!` macro?
69/// As mentioned above under section "[*Safety*](#safety)", dereferencing a `Deferred<&mut T>` will invalidate any other [Deferred] instances 
70/// which are not re-borrowed, even the ones created by the [`defer`](macro@defer) macro (`Deferred<&T>` instances returned by the
71/// [`defer`](macro@defer) macro do not constitute as re-borrows). This means that the [`defer`](macro@defer) macro is only safe to use
72/// together with the [`defer_mut`](macro@defer_mut) macro if you take special care to always call [`defer!`](macro@defer) again to refresh
73/// its pointer, after a mutable reference has been given out through dereferencing the `Deferred<&mut T>.` For example, this is definately
74/// __considered undefined behavior__:
75/// ```no_run
76/// #[macro_use]
77/// extern crate deferred_reference;
78/// use deferred_reference::Deferred;
79/// fn main() {
80///     let mut buffer = [0u8; 1024];
81///     // SAFETY: what we are about to do is very unsafe!
82///     let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
83///     let deferred: Deferred<&[u8]> =  unsafe { defer!(buffer) };
84///     assert_eq!(0, deferred_mut[0]);
85///     assert_eq!(0, deferred[0]); // so far so good, no UB yet...
86///     deferred_mut[0] = 42; // this implicity creates a mutable reference to `buffer`
87///     // `deferred` is now invalidated!
88///     assert_eq!(42, deferred_mut[0]); // this is not yet UB...
89///     assert_eq!(42, deferred[0]); // this is UB!
90/// }
91/// ```
92/// The undefined behavior can be side-stepped if the deferred mutable reference is re-borrowed, like so:
93/// ```
94/// #[macro_use]
95/// extern crate deferred_reference;
96/// use deferred_reference::Deferred;
97/// fn main() {
98///     let mut buffer = [0u8; 1024];
99///     // SAFETY: this is safe because we reborrow `deferred_mut` and
100///     // SAFETY: we don't create any overlapping references.
101///     let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
102///     let deferred: Deferred<&[u8]> = unsafe { deferred_mut.clone_unchecked().into_ref() };
103///     assert_eq!(0, deferred_mut[0]);
104///     assert_eq!(0, deferred[0]);
105///     deferred_mut[0] = 42; // this implicity creates a mutable reference to `buffer`
106///     assert_eq!(42, deferred_mut[0]);
107///     assert_eq!(42, deferred[0]); // but this is not UB thanks the re-borrow
108/// }
109/// ```
110/// If the calls to the [`defer`](macro@defer) macro are timed well, then it is possible to combine
111/// the two macros without running into undefined behavior:
112/// ```
113/// #[macro_use]
114/// extern crate deferred_reference;
115/// use deferred_reference::Deferred;
116/// fn main() {
117///     let mut buffer = [0u8; 1024];
118///     // SAFETY: this is safe, because we create new deferred references after
119///     // SAFETY: dereferencing `deferred_mut` into an actual mutable reference.
120///     let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
121///     let mut deferred: Deferred<&[u8]> = unsafe { defer!(buffer) };
122///     assert_eq!(0, deferred_mut[0]);
123///     assert_eq!(0, deferred[0]);
124///     deferred_mut[0] = 42; // this implicity creates a temporary mutable reference to `buffer`
125///     // `deferred` is now invalidated! we refresh it again:
126///     deferred = unsafe { defer!(buffer) };
127///     assert_eq!(42, deferred_mut[0]);
128///     // this is not UB, because the mutable reference did not overlap
129///     // with the re-creation of `deferred`:
130///     assert_eq!(42, deferred[0]); 
131/// }
132/// ```
133/// The previous 3 examples consist of very unsafe Rust and should not be attempted unless there
134/// exists a specific reason why this is needed and the implementor has intricate knowledge
135/// about raw pointer management in Rust. In all other cases, using the [DeferMut::defer_mut]
136/// is the much better alternative to the [`defer_mut`](macro@defer_mut) macro.
137#[macro_export]
138macro_rules! defer_mut {
139    ($place:expr) => {
140        $crate::Deferred::from_raw_mut(core::ptr::addr_of_mut!($place))
141    };
142}
143
144/// The [DeferMut] trait offers easy access to deferred mutable references
145/// to types that implement [DeferMut]. This trait is already implemented on all types `T: ?Sized` for
146/// [`UnsafeCell<T>`](core::cell::UnsafeCell) out-of-the-box and this should be sufficient for most purposes,
147/// but it is also possible to implement the [Defer] and [DeferMut] traits for your own types, please see
148/// the documentation of this trait on how to do this safely.
149/// 
150/// # Safety
151/// This trait may only be implemented for:
152/// 1. All types that support interior mutability. Concretely, this means that
153/// for types that have interior mutability, the type must contain an [UnsafeCell] or one of
154/// of its derivatives, such as those in the Rust standard library like `RefCell`, `RwLock` or `Mutex`.
155/// 2. Other smart-pointers which do not "own" their data. Smart-pointers which contain a
156/// mutable pointer `*mut T` don't need to wrap the mutable pointer in an [UnsafeCell], because
157/// dereferencing a mutable pointer does not constitute interior mutability.
158///
159/// Additionally, all types that implement [DeferMut] must uphold the following invariants:
160/// * The type must also implement the [Defer] trait.
161/// * The deferred reference that the [DeferMut::defer_mut] method returns, must point to the same location
162///   as the [Deferred] returned by [Defer::defer].
163/// * Both the [Defer] and [DeferMut] trait implementations may not create any references
164///   to the location where the returned [Deferred] points, nor may the location
165///   be accessed in any way (e.g. dereferencing). Taking an immutable shared reference to a wrapping [UnsafeCell]
166///   is okay, but creating a reference to the contents of the [UnsafeCell] is not! Creating a
167///   mutable reference to the wrapping [UnsafeCell] is also not okay, because [UnsafeCell] only protects
168///   shared references to a place that may be mutated, it does not weaken the rules for mutable references,
169///   which say that a mutable reference must be exclusive in order to stay clear of undefined behavior.
170///
171/// # Example
172/// Here is an example for how to implement this trait for custom smart pointers.
173/// ```
174/// use deferred_reference::{Defer, DeferMut, Deferred};
175/// /// `MemoryMappedBuffer` is a simplified representation of a memory mapped slice of bytes.
176/// /// Proper implementations would also contain a `MemoryMappedBuffer::new` constructor
177/// /// which sets up the owned memory map and `MemoryMappedBuffer` should also implement
178/// /// the `Drop` trait to properly clean up the memory map when `MemoryMappedBuffer`
179/// /// goes out of scope.
180/// pub struct MemoryMappedBuffer {
181///     ptr: *mut u8,
182///     length: usize,
183/// }
184/// impl Defer for MemoryMappedBuffer {
185///     type Target = [u8];
186///     fn defer(&self) -> Deferred<&[u8]> {
187///         let slice_ptr = core::ptr::slice_from_raw_parts(self.ptr as *const u8, self.length);
188///         // SAFETY: this is safe because the Deferred occupies a shared reference to the
189///         // SAFETY: smart pointer `MemoryMappedBuffer` for the duration of lifetime of &self,
190///         // SAFETY: which means no other callers can safely obtain a mutable reference
191///         // SAFETY: the MemoryMappedBuffer instance.
192///         unsafe { Deferred::from_raw(slice_ptr) }
193///     }
194/// }
195/// // SAFETY: this is safe, because the invariant of `Deferred` is upheld.
196/// // SAFETY: this is only safe if the memory mapped region is properly aligned and initialized
197/// // SAFETY: and `ptr` is non-null and not dangling (i.e. it must point to a valid memory region).
198/// unsafe impl DeferMut for MemoryMappedBuffer {
199///     unsafe fn defer_mut(&self) -> Deferred<&mut [u8]> {
200///         let slice_mut_ptr = core::ptr::slice_from_raw_parts_mut(self.ptr, self.length);
201///         Deferred::from_raw_mut(slice_mut_ptr)
202///     }
203/// }
204/// ```
205/// If you want to build your own custom smart pointer that also owns the backing memory,
206/// then you can use `Vec`, `Box` and `UnsafeCell` to do so through interior mutability like this:
207/// ```
208/// use deferred_reference::{Defer, DeferMut, Deferred};
209/// use core::ops::{Deref, DerefMut};
210/// use core::cell::UnsafeCell;
211/// pub struct MyBuffer {
212///     memory: Box<UnsafeCell<[u8]>>,
213/// }
214/// impl MyBuffer {
215///     fn new(capacity: usize) -> Self {
216///         let mut vector = Vec::with_capacity(capacity);
217///         // we have to initialize the full vector, otherwise it is undefined behavior
218///         // when we give out references to the backing slice of bytes.
219///         vector.resize(capacity, 0u8);
220///         let boxed_slice: Box<[u8]> = vector.into_boxed_slice();
221///         // SAFETY: UnsafeCell is #[repr(transparent)] so this is safe.
222///         let memory: Box<UnsafeCell<[u8]>> = unsafe { core::mem::transmute(boxed_slice) };
223///         Self { memory }
224///     }
225/// }
226/// // we only need to implement Deref, because the Defer and DeferMut
227/// // traits are already implemented for UnsafeCell<[u8]>.
228/// impl Deref for MyBuffer {
229///     type Target = UnsafeCell<[u8]>;
230///     fn deref(&self) -> &Self::Target {
231///         self.memory.deref()
232///     }
233/// }
234/// // we also implement DerefMut just to illustrate the invalidation of
235/// // Deferred when taking out a mutable borrow. this is optional.
236/// impl DerefMut for MyBuffer {
237///     fn deref_mut(&mut self) -> &mut Self::Target {
238///         self.memory.deref_mut()
239///     }
240/// }
241/// fn main() {
242///     let mut my_buffer = MyBuffer::new(1024 * 100); // 100kb buffer
243///     // SAFETY: this is safe, because there exist no references to the slice.
244///     let deferred_mut: Deferred<&mut [u8]> = unsafe { my_buffer.defer_mut() };
245///     // the next line implicitly calls Deref::deref() on `my_buffer`.
246///     // this is also okay, because the slice sits inside an UnsafeCell.
247///     let deferred: Deferred<&[u8]> = my_buffer.defer();
248///     // the next statement is also safe, because by taking out a `&mut self` on MyBuffer
249///     // the deferred references are invalidated due to their lifetimes.
250///     // this implicitly calls DerefMut::deref_mut() and then UnsafeCell::get_mut():
251///     let mut_ref: &mut [u8] = my_buffer.get_mut();
252///     // with the next statement uncommmented, the above statement will error:
253///     // "cannot borrow `my_buffer` as mutable because it is also borrowed as immutable"
254///     //let mut_ref2: &mut [u8] = deferred_mut.deref_mut(); // uncomment for error
255/// }
256/// ```
257pub unsafe trait DeferMut: Defer {
258    /// Obtain a deferred mutable reference to [Defer::Target].
259    /// 
260    /// # Example
261    /// ```
262    /// use deferred_reference::{Defer, DeferMut};
263    /// use core::cell::UnsafeCell;
264    /// let buffer = UnsafeCell::new([0u8; 1024]);
265    /// // calling defer() or defer_mut() immutably borrows `buffer` for as long
266    /// // as the returned `Deferred` is in use.
267    /// let deferred = buffer.defer();
268    /// // SAFETY: this is safe, because we promise not to create an overlapping mutable reference
269    /// let mut deferred_mut = unsafe { buffer.defer_mut() };
270    /// // both `deferred` and `deferred_mut` can be safely immutably dereferenced simultaneously:
271    /// assert_eq!(&deferred[0], &deferred_mut[0]);
272    /// // we can mutate the `buffer` through `deferred_mut` as any other array.
273    /// // this implicity creates a temporary mutable reference into the array inside `buffer`.
274    /// // even though an immutable reference to `buffer` exists, this is okay because
275    /// // the inner array sits inside an `UnsafeCell` which allows interior mutability:
276    /// deferred_mut[0] = 42; 
277    /// // and observe the change through `deferred`:
278    /// assert_eq!(deferred[0], 42);
279    /// // all this time, both deferred references are alive, but because
280    /// // these are not actual references, this doesn't violate the Rust borrow
281    /// // rules and this is not undefined behavior. The lifetimes of the mutable
282    /// // and immutable references derived from the Deferred do not overlap,
283    /// // so the Rust borrow rules are respected all this time.
284    /// assert_eq!(&deferred[0], &deferred_mut[0]);
285    /// // this also works for multiple deferred mutable references!
286    /// // SAFETY: this is safe, because we promise not to create overlapping references
287    /// let mut deferred_mut2 = unsafe { buffer.defer_mut() };
288    /// // we can mutate the buffer through 2 distinct deferred mutable references
289    /// // (as long as we don't do this at the same time!)
290    /// deferred_mut[0] += 1;
291    /// deferred_mut2[0] += 1;
292    /// assert_eq!(44, deferred[0]);
293    /// assert_eq!(deferred_mut[0], deferred_mut2[0]);
294    /// // because `Deferred` implements the `Index` and `IndexMut` trait, it is possible
295    /// // to create two references that overlap in lifetime, but are disjoint in index:
296    /// assert_eq!(&mut deferred_mut[1], &mut deferred_mut2[2]); // indices are disjoint, so no UB
297    /// ```
298    ///
299    /// # Safety
300    /// This method is unsafe, because it is possible to call it more than once. This is in contrast
301    /// to the regular Rust borrowing rules, where it is only allowed to have one mutable borrow at
302    /// a time. [Deferred] instances are not actual references and this is why this is not considered
303    /// undefined behavior. However, the absence of instant undefined behavior does not make this
304    /// method safe. [Deferred] also implements the [DerefMut](core::ops::DerefMut) trait, which lets
305    /// anyone call `<Deferred as DerefMut>::deref_mut(&mut self)` on the [Deferred] and this creates
306    /// an actual mutable reference from safe code. Hence, this method must be marked as unsafe,
307    /// otherwise it could lead to unsoundness when creating multiple mutable references from safe code.
308    /// The caller must take special care not to create any references (mutable or immutable) that
309    /// may overlap with the actual mutable reference created from the returned [`Deferred<&mut T>`](Deferred).
310    /// Note that overlap means a reference to the same region during the same lifetime. If two
311    /// [Deferred] both create a reference to the same region, but with disjoint lifetimes, then
312    /// this is safe.
313    unsafe fn defer_mut(&self) -> Deferred<&mut Self::Target>;
314}
315
316unsafe impl<T: ?Sized> DeferMut for UnsafeCell<T> {
317    unsafe fn defer_mut(&self) -> Deferred<&mut T> {
318        Deferred::from_raw_mut(self.get())
319    }
320}
321
322unsafe impl<T: ?Sized> DeferMut for Deferred<&mut T> {
323    unsafe fn defer_mut(&self) -> Deferred<&mut Self::Target> {
324        Deferred::from_raw_mut(self.as_mut_ptr())
325    }
326}
327
328#[cfg(test)]
329mod tests {
330    use crate::{Defer, DeferMut};
331    use core::cell::UnsafeCell;
332
333    /// this test is identical to the example doctest of [DeferMut],
334    /// but it is repeated here because Miri does not support doctests yet.
335    #[test]
336    fn doc_test() {
337        let buffer = UnsafeCell::new([0u8; 1024]);
338        // calling defer() or defer_mut() immutably borrows `buffer` for as long
339        // as the returned `Deferred` is in use.
340        let deferred = buffer.defer();
341        // SAFETY: this is safe, because we promise not to create overlapping references
342        let mut deferred_mut = unsafe { buffer.defer_mut() };
343        // both `deferred` and `deferred_mut` can be safely immutably dereferenced:
344        assert_eq!(&deferred[0], &deferred_mut[0]);
345        // we can mutate the `buffer` through `deferred_mut` as any other array.
346        // this implicity creates a temporary mutable reference into the array inside `buffer`.
347        // even though an immutable reference to `buffer` exists, this is okay because
348        // the inner array sits inside an `UnsafeCell` which allows interior mutability:
349        deferred_mut[0] = 42;
350        // and observe the change through `deferred`:
351        assert_eq!(deferred[0], 42);
352        // all this time, both deferred references are alive, but because
353        // these are not actual references, this doesn't violate the Rust borrow
354        // rules and this is not undefined behavior. The lifetimes of the mutable
355        // and immutable references derived from the Deferred do not overlap,
356        // so the Rust borrow rules are respected all this time.
357        assert_eq!(&deferred[0], &deferred_mut[0]);
358        // this also works for multiple deferred mutable references!
359        // SAFETY: this is safe, because we promise not to create overlapping references
360        let mut deferred_mut2 = unsafe { buffer.defer_mut() };
361        // we can mutate the buffer through 2 distinct deferred mutable references
362        // (as long as we don't do this at the same time!)
363        deferred_mut[0] += 1;
364        deferred_mut2[0] += 1;
365        assert_eq!(44, deferred[0]);
366        assert_eq!(deferred_mut[0], deferred_mut2[0]);
367        // however, the following is not okay, because this would create two overlapping
368        // mutable references and this is undefined behavior (hence the use of `unsafe` above):
369        //assert_eq!(&mut deferred_mut[0], &mut deferred_mut2[0]);
370        // because `Deferred` implements the `Index` and `IndexMut` trait, it is possible
371        // to create two references that overlap in lifetime, but are disjoint in index:
372        assert_eq!(&mut deferred_mut[1], &mut deferred_mut2[2]); // indices are disjoint, so no UB
373    }
374
375    mod defer_mut_macro {
376        use crate::{defer, Deferred};
377        #[test]
378        fn call_macro() {
379            let mut buffer = [1u8; 1024];
380            let mut deferred = unsafe { defer_mut!(buffer) };
381            assert_eq!(buffer[0], deferred[0]);
382            deferred[0] = 2;
383            assert_eq!(2, buffer[0]);
384        }
385        // /// this triggers UB in miri, because deferred gets invalidated
386        // #[test]
387        // fn example_ub() {
388        //     let mut buffer = [2u8; 1024];
389        //     let deferred = unsafe { defer_mut!(buffer) };
390        //     // this is undefined behavior:
391        //     buffer[0] = 42; // because this implicitly creates a temporary mutable reference
392        //     assert_eq!(buffer[0], deferred[0]);
393        // }
394        
395        #[test]
396        fn assert_no_reference_created() {
397            let mut buffer = [3u8; 1024];
398            let mut deferred = unsafe { defer_mut!(buffer) };
399            assert_eq!(&3, &buffer[0]); // this implicitly creates a temporary immutable reference to all of `buffer`
400            // this is undefined behavior:
401            //buffer[0] = 42; // because this implicitly creates a temporary mutable reference to all of `buffer`, which invalidates `deferred`
402            // but this is not undefined behavior:
403            deferred[0] = 42; // because the mutable pointer to `buffer` inside `deferred` is re-borrowed
404            assert_eq!(buffer[0], deferred[0]);
405            assert_eq!(42, buffer[0]);
406        }
407
408        /// extra test to ensure the doctest above doesn't cause UB (miri doesn't work on doctests yet)
409        #[test]
410        fn doc_test() {
411            let mut buffer = [0u8; 1024];
412            let deferred: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
413            assert_eq!(buffer[0], deferred[0]);
414            // works also for references to arrays:
415            let deferred: Deferred<&mut [u8; 1024]> =  unsafe { defer_mut!(buffer) };
416            assert_eq!(buffer[0], deferred[0]);
417        }
418
419        /// canary test to see if mutable references reborrowed from Deferred invalidate other Deferred.
420        /// (so far miri doesn't complain here yet)
421        #[test]
422        fn overlapping_deferreds() {
423            let mut buffer = [3u8; 1024];
424            let mut deferred1 = unsafe { defer_mut!(buffer) };
425            let mut deferred2 = unsafe { defer_mut!(buffer) };
426            assert_eq!(&mut 3, &mut deferred1[0]);
427            assert_eq!(&mut 3, &mut deferred2[0]);
428            assert_eq!(&mut 3, &mut deferred1[0]);
429            deferred1[0] = 42;
430            deferred2[1] = 42;
431            assert_eq!(&mut 42, &mut deferred2[0]);
432            assert_eq!(&mut 42, &mut deferred1[0]);
433            assert_eq!(&mut 42, &mut deferred2[0]);
434            assert_eq!(&deferred1[..], &deferred2[..]);
435        }
436
437        #[test]
438        fn mixing_defer_and_defer_mut() {
439            let mut buffer = [0u8; 1024];
440            let deferred: Deferred<&[u8]> =  unsafe { crate::defer!(buffer) };
441            assert_eq!(0, deferred[0]);
442            let mut deferred_mut: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
443            assert_eq!(0, deferred[0]); // deferred is still valid
444            deferred_mut[0] = 42;
445            assert_eq!(42, deferred_mut[0]);
446            // the previous line created a mutable reference, so we need to re-obtain Deferred<&[u8]>
447            let deferred: Deferred<&[u8]> =  unsafe { crate::defer!(buffer) }; // omitting this line is UB!
448            assert_eq!(42, deferred[0]);
449            assert_eq!(42, deferred_mut[0]);
450        }
451        #[test]
452        fn mixing_defer_and_defer_mut2() {
453            let mut buffer = [0u8; 1024];
454            let mut deferred_mut: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
455            assert_eq!(0, deferred_mut[0]);
456            let deferred: Deferred<&[u8]> =  unsafe { crate::defer!(buffer) };
457            assert_eq!(0, deferred[0]);
458            deferred_mut[0] = 42;
459            assert_eq!(42, deferred_mut[0]);
460            // the previous line created a mutable reference, so we need to re-obtain Deferred<&[u8]>
461            let deferred: Deferred<&[u8]> =  unsafe { crate::defer!(buffer) }; // omitting this line is UB!
462            assert_eq!(42, deferred[0]);
463            assert_eq!(42, deferred_mut[0]);
464        }
465        #[test]
466        fn mixing_defer_and_defer_mut3() {
467            let mut buffer = [0u8; 1024];
468            let mut deferred_mut: Deferred<&mut [u8]> =  unsafe { defer_mut!(buffer) };
469            assert_eq!(0, deferred_mut[0]);
470            // here we create a deferred immutable reference which reborrows the pointer:
471            let deferred: Deferred<&[u8]> = unsafe { deferred_mut.clone_unchecked().into() };   
472            assert_eq!(0, deferred[0]);
473            deferred_mut[0] = 42;
474            assert_eq!(42, deferred[0]); // NOT UB! thanks to the reborrow
475            assert_eq!(42, deferred_mut[0]);
476        }
477
478        #[test]
479        fn doctest_defer1() {
480            let mut buffer = [0u8; 1024];
481            // SAFETY: what we are about to do is very unsafe!
482            let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
483            let deferred: Deferred<&[u8]> =  unsafe { defer!(buffer) };
484            assert_eq!(0, deferred_mut[0]);
485            assert_eq!(0, deferred[0]); // so far so good, no UB yet...
486            deferred_mut[0] = 42; // this implicity creates a mutable reference to `buffer`
487            // `deferred` is now invalidated!
488            assert_eq!(42, deferred_mut[0]);
489            //assert_eq!(42, deferred[0]); // this is UB!
490        }
491        #[test]
492        fn doctest_defer2() {
493            let mut buffer = [0u8; 1024];
494            // SAFETY: this is safe because we reborrow `deferred_mut` and
495            // SAFETY: we don't create any overlapping references.
496            let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
497            let deferred: Deferred<&[u8]> = unsafe { deferred_mut.clone_unchecked().into_ref() };
498            assert_eq!(0, deferred_mut[0]);
499            assert_eq!(0, deferred[0]);
500            deferred_mut[0] = 42; // this implicity creates a mutable reference to `buffer`
501            assert_eq!(42, deferred_mut[0]);
502            assert_eq!(42, deferred[0]); // but this is not UB thanks the re-borrow
503        }
504        #[test]
505        fn doctest_defer3() {
506            let mut buffer = [0u8; 1024];
507            // SAFETY: this is safe, because we create new deferred references after
508            // SAFETY: dereferencing `deferred_mut` into an actual mutable reference.
509            let mut deferred_mut: Deferred<&mut [u8]> = unsafe { defer_mut!(buffer) };
510            let mut deferred: Deferred<&[u8]> = unsafe { defer!(buffer) };
511            assert_eq!(0, deferred_mut[0]);
512            assert_eq!(0, deferred[0]); // so far so good, no UB yet...
513            deferred_mut[0] = 42; // this implicity creates a temporary mutable reference to `buffer`
514            // `deferred` is now invalidated! we refresh it again:
515            deferred = unsafe { defer!(buffer) };
516            assert_eq!(42, deferred_mut[0]);
517            // this is not UB, because the mutable reference did not overlap
518            // with the re-creation of `deferred`:
519            assert_eq!(42, deferred[0]); 
520        }
521    }
522}