abi_stable/sabi_types/
rmut.rs

1use std::{
2    fmt::{self, Display},
3    marker::PhantomData,
4    ptr::NonNull,
5};
6
7use crate::{
8    pointer_trait::{AsMutPtr, AsPtr, CanTransmuteElement, GetPointerKind, PK_MutReference},
9    sabi_types::RRef,
10};
11
12/// Equivalent to `&'a mut T`,
13/// which allows a few more operations without causing Undefined Behavior.
14///
15/// # Purpose
16///
17/// This type is used as the `&mut self` parameter in abi_stable trait objects
18/// because it can be soundly transmuted
19/// to point to other smaller but compatible types, then back to the original type.
20///
21/// This crate is tested with [miri] to detect bugs in unsafe code,
22/// which implements the  [Stacked Borrows model].
23/// Because that model forbids `&mut T` to `&mut ()`  to `&mut T` transmutes
24/// (when `T` isn't zero-sized),
25/// it required defining `RMut` to allow a mutable-reference-like type that can be transmuted.
26///
27/// # Example
28///
29/// This example demonstrates how a simple `&mut dyn Any`-like type can be implemented.
30///
31/// ```rust
32/// use abi_stable::{marker_type::ErasedObject, std_types::UTypeId, RMut};
33///
34/// fn main() {
35///     let mut value = WithTypeId::new(5u32);
36///     let mut clone = value.clone();
37///     let mut erased = value.erase();
38///
39///     assert_eq!(WithTypeId::downcast::<i32>(erased.reborrow()), None);
40///     assert_eq!(WithTypeId::downcast::<bool>(erased.reborrow()), None);
41///     assert_eq!(
42///         WithTypeId::downcast::<u32>(erased.reborrow()),
43///         Some(&mut clone)
44///     );
45/// }
46///
47/// // `#[repr(C))]` with a trailing `T` field is required for soundly transmuting from
48/// // `RMut<'a, WithTypeId<T>>` to `RMut<'a, WithTypeId<ErasedObject>>`.
49/// #[repr(C)]
50/// #[derive(Debug, PartialEq, Clone)]
51/// struct WithTypeId<T> {
52///     type_id: UTypeId,
53///     value: T,
54/// }
55///
56/// impl<T> WithTypeId<T> {
57///     pub fn new(value: T) -> Self
58///     where
59///         T: 'static,
60///     {
61///         Self {
62///             type_id: UTypeId::new::<T>(),
63///             value,
64///         }
65///     }
66///
67///     pub fn erase(&mut self) -> RMut<'_, WithTypeId<ErasedObject>> {
68///         unsafe { RMut::new(self).transmute::<WithTypeId<ErasedObject>>() }
69///     }
70/// }
71///
72/// impl WithTypeId<ErasedObject> {
73///     pub fn downcast<T>(this: RMut<'_, Self>) -> Option<&mut WithTypeId<T>>
74///     where
75///         T: 'static,
76///     {
77///         if this.get().type_id == UTypeId::new::<T>() {
78///             // safety: we checked that type parameter was `T`
79///             unsafe { Some(this.transmute_into_mut::<WithTypeId<T>>()) }
80///         } else {
81///             None
82///         }
83///     }
84/// }
85///
86///
87/// ```
88///
89/// <span id="type-prefix-exp"></span>
90/// # Type Prefix
91///
92/// A type parameter `U` is considered a prefix of `T` in all of these cases:
93///
94/// - `U` is a zero-sized type with an alignment equal or lower than `T`
95///
96/// - `U` is a `#[repr(transparent)]` wrapper over `T`
97///
98/// - `U` and `T` are both `#[repr(C)]` structs,
99/// in which `T` starts with the fields of `U` in the same order,
100/// and `U` has an alignment equal to or lower than `T`.
101///
102/// Please note that it can be unsound to transmute a non-local
103/// type if it has private fields,
104/// since it may assume it was constructed in a particular way.
105///
106/// [Stacked Borrows model]:
107/// https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md
108///
109/// [miri]: https://github.com/rust-lang/miri
110///
111#[repr(transparent)]
112#[derive(StableAbi)]
113#[sabi(bound(T:'a))]
114pub struct RMut<'a, T> {
115    ref_: NonNull<T>,
116    _marker: PhantomData<crate::utils::MutRef<'a, T>>,
117}
118
119impl<'a, T> Display for RMut<'a, T>
120where
121    T: Display,
122{
123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124        Display::fmt(self.get(), f)
125    }
126}
127
128unsafe impl<'a, T> Sync for RMut<'a, T> where &'a T: Sync {}
129
130unsafe impl<'a, T> Send for RMut<'a, T> where &'a T: Send {}
131
132shared_impls! {
133    mod=static_ref_impls
134    new_type=RMut['a][T],
135    original_type=AAAA,
136    deref_approach=(method = get),
137}
138
139impl<'a, T> RMut<'a, T> {
140    /// Constructs this RMut from a mutable reference
141    ///
142    /// # Example
143    ///
144    /// ```rust
145    /// use abi_stable::RMut;
146    ///
147    /// let mut foo = 3;
148    /// let mut rmut = RMut::new(&mut foo);
149    /// *rmut.get_mut() += 10;
150    ///
151    /// assert_eq!(*rmut.get(), 13);
152    /// assert_eq!(foo, 13);
153    ///
154    /// ```
155    #[inline(always)]
156    pub fn new(ref_: &'a mut T) -> Self {
157        unsafe {
158            Self {
159                ref_: NonNull::new_unchecked(ref_),
160                _marker: PhantomData,
161            }
162        }
163    }
164
165    /// Constructs this RMut from a raw pointer.
166    ///
167    /// # Safety
168    ///
169    /// You must ensure that the raw pointer is valid for the `'a` lifetime,
170    /// points to a fully initialized and aligned `T`,
171    /// and that this is the only active pointer to that value.
172    ///
173    /// # Example
174    ///
175    /// ```rust
176    /// use abi_stable::RMut;
177    ///
178    /// let mut foo = 3u32;
179    /// // safety:
180    /// // `&mut foo` is casted to a pointer to a compatible type (`u32` to `i32`),
181    /// // `rmut` is only used for the lifetime of foo,
182    /// // and is the only active pointer to `foo` while it's used.
183    /// let mut rmut = unsafe { RMut::from_raw((&mut foo) as *mut u32 as *mut i32) };
184    /// *rmut.get_mut() -= 4;
185    ///
186    /// assert_eq!(*rmut.get(), -1);
187    /// assert_eq!(foo, !0);
188    ///
189    /// ```
190    #[inline(always)]
191    pub const unsafe fn from_raw(ref_: *mut T) -> Self
192    where
193        T: 'a,
194    {
195        Self {
196            ref_: unsafe { NonNull::new_unchecked(ref_) },
197            _marker: PhantomData,
198        }
199    }
200
201    /// Reborrows this `RMut`, with a shorter lifetime.
202    ///
203    /// This allows passing an `RMut` to functions multiple times,
204    /// but with a shorter lifetime argument.
205    ///
206    /// # Example
207    ///
208    /// ```rust
209    /// use abi_stable::RMut;
210    ///
211    /// let mut foo = 3;
212    /// let mut rmut = RMut::new(&mut foo);
213    ///
214    /// assert_eq!(mutate(rmut.reborrow()), 6);
215    /// assert_eq!(mutate(rmut.reborrow()), 12);
216    /// assert_eq!(mutate(rmut.reborrow()), 24);
217    ///
218    /// // last use of rmut, so it can be moved instead of being reborrowed.
219    /// assert_eq!(mutate(rmut), 48);
220    ///
221    /// fn mutate(mut rmut: RMut<'_, u32>) -> u32 {
222    ///     *rmut.get_mut() *= 2;
223    ///     rmut.get_copy()
224    /// }
225    ///
226    /// ```
227    #[inline(always)]
228    pub fn reborrow(&mut self) -> RMut<'_, T> {
229        RMut {
230            ref_: self.ref_,
231            _marker: PhantomData,
232        }
233    }
234
235    /// Reborrows this `RMut` into a shared reference.
236    ///
237    /// Note that because the reference reborrows this `RMut<'a, T>`
238    /// its lifetime argument is strictly smaller.
239    /// To turn an `RMut<'a, T>` into a `&'a T` (with the same lifetime argument)
240    /// you can use [`into_ref`](#method.into_ref).
241    ///
242    ///
243    /// # Example
244    ///
245    /// ```rust
246    /// use abi_stable::RMut;
247    ///
248    /// let mut val = 89;
249    /// let rmut = RMut::new(&mut val);
250    ///
251    /// assert_eq!(rmut.get(), &89);
252    ///
253    /// ```
254    ///
255    /// ### Lifetimes
256    ///
257    /// This demonstrates when `into_ref` works, but `get` doesn't.
258    ///
259    /// ```rust
260    /// # use abi_stable::RMut;
261    /// fn stuff<'a>(x: RMut<'a, i32>) -> &'a i32 {
262    ///     x.into_ref()
263    /// }
264    /// ```
265    ///
266    /// This doesn't compile, because `get` reborrows `foo`.
267    /// ```compile_fail
268    /// # use abi_stable::RMut;
269    /// fn stuff<'a>(foo: RMut<'a, i32>) -> &'a i32 {
270    ///     foo.get()
271    /// }
272    /// ```
273    #[inline(always)]
274    pub const fn get(&self) -> &T {
275        unsafe { crate::utils::deref!(self.ref_.as_ptr()) }
276    }
277
278    /// Copies the value that this `RMut` points to.
279    ///
280    /// # Example
281    ///
282    /// ```rust
283    /// use abi_stable::RMut;
284    ///
285    /// let mut val = "hello";
286    /// let mut rmut = RMut::new(&mut val);
287    ///
288    /// *rmut.get_mut() = "world";
289    ///
290    /// assert_eq!(rmut.get_copy(), "world");
291    ///
292    /// ```
293    #[inline(always)]
294    pub const fn get_copy(&self) -> T
295    where
296        T: Copy,
297    {
298        unsafe { *(self.ref_.as_ptr() as *const T) }
299    }
300
301    /// Converts this `RMut<'a, T>` into a `&'a T`
302    ///
303    /// # Example
304    ///
305    /// ```rust
306    /// use abi_stable::RMut;
307    ///
308    /// let mut val = 89;
309    ///
310    /// assert_eq!(mutate(RMut::new(&mut val)), &44);
311    ///
312    /// fn mutate(mut rmut: RMut<'_, u32>) -> &u32 {
313    ///     *rmut.get_mut() /= 2;
314    ///     rmut.into_ref()
315    /// }
316    ///
317    /// ```
318    ///
319    #[inline(always)]
320    pub const fn into_ref(self) -> &'a T {
321        unsafe { crate::utils::deref!(self.ref_.as_ptr()) }
322    }
323
324    /// Reborrows this `RMut` into a mutable reference.
325    ///
326    /// Note that because the mutable reference reborrows this `RMut<'a, T>`
327    /// its lifetime argument is strictly smaller.
328    /// To turn an `RMut<'a, T>` into a `&'a mut T` (with the same lifetime argument)
329    /// you can use [`into_mut`](#method.into_mut).
330    ///
331    /// # Example
332    ///
333    /// ```rust
334    /// use abi_stable::RMut;
335    ///
336    /// let mut val = 89;
337    /// let mut rmut = RMut::new(&mut val);
338    ///
339    /// assert_eq!(rmut.get_mut(), &mut 89);
340    ///
341    /// *rmut.get_mut() += 10;
342    ///
343    /// assert_eq!(rmut.get_mut(), &mut 99);
344    ///
345    /// ```
346    ///
347    /// ### Lifetimes
348    ///
349    /// This demonstrates when `into_mut` works, but `get_mut` doesn't.
350    ///
351    /// ```rust
352    /// # use abi_stable::RMut;
353    /// fn stuff<'a>(x: RMut<'a, i32>) -> &'a mut i32 {
354    ///     x.into_mut()
355    /// }
356    /// ```
357    ///
358    /// This doesn't compile, because `get_mut` reborrows `foo`.
359    /// ```compile_fail
360    /// # use abi_stable::RMut;
361    /// fn stuff<'a>(mut foo: RMut<'a, i32>) -> &'a mut i32 {
362    ///     foo.get_mut()
363    /// }
364    /// ```
365    #[inline(always)]
366    pub fn get_mut(&mut self) -> &mut T {
367        unsafe { &mut *self.ref_.as_ptr() }
368    }
369
370    /// Converts this `RMut<'a, T>` into a `&'a mut T`
371    ///
372    /// # Example
373    ///
374    /// ```rust
375    /// use abi_stable::RMut;
376    ///
377    /// let mut val = 13;
378    ///
379    /// let rmut = RMut::new(&mut val);
380    ///
381    /// assert_eq!(rmut.get(), &13);
382    ///
383    /// *rmut.into_mut() += 8;
384    ///
385    /// assert_eq!(val, 21);
386    ///
387    /// ```
388    #[inline(always)]
389    pub fn into_mut(self) -> &'a mut T {
390        unsafe { &mut *self.ref_.as_ptr() }
391    }
392
393    /// Reborrows this `RMut` as a const raw pointer.
394    ///
395    /// # Example
396    ///
397    /// ```rust
398    /// use abi_stable::RMut;
399    ///
400    /// let mut val = 34;
401    /// let rmut = RMut::new(&mut val);
402    ///
403    /// unsafe {
404    ///     assert_eq!(*rmut.as_ptr(), 34);
405    /// }
406    /// ```
407    #[inline]
408    pub const fn as_ptr(&self) -> *const T {
409        self.ref_.as_ptr()
410    }
411
412    /// Reborrows this `RMut` as a mutable raw pointer.
413    ///
414    /// # Example
415    ///
416    /// ```rust
417    /// use abi_stable::RMut;
418    ///
419    /// let mut val = 34;
420    /// let mut rmut = RMut::new(&mut val);
421    ///
422    /// unsafe {
423    ///     rmut.as_mut_ptr().write(7);
424    ///
425    ///     *rmut.as_mut_ptr() *= 2;
426    ///
427    ///     assert_eq!(val, 14);
428    /// }
429    /// ```
430    #[inline]
431    pub fn as_mut_ptr(&mut self) -> *mut T {
432        self.ref_.as_ptr()
433    }
434
435    /// Converts this `RMut<'a, T>` into a `*mut T`
436    ///
437    /// # Example
438    ///
439    /// ```rust
440    /// use abi_stable::RMut;
441    ///
442    /// let mut val = 89;
443    /// let rmut = RMut::new(&mut val);
444    ///
445    /// unsafe {
446    ///     let ptr = rmut.into_raw();
447    ///
448    ///     ptr.write(27);
449    ///
450    ///     *ptr += 2;
451    ///
452    ///     assert_eq!(val, 29);
453    /// }
454    /// ```
455    #[inline]
456    pub const fn into_raw(self) -> *mut T {
457        self.ref_.as_ptr()
458    }
459
460    /// Transmutes this `RMut<'a, T>` to a `*mut U`.
461    ///
462    /// # Example
463    ///
464    /// ```rust
465    /// use abi_stable::RMut;
466    ///
467    /// let mut val = Direction::Up;
468    /// let rmut = RMut::new(&mut val);
469    ///
470    /// assert_eq!(rmut.get(), &Direction::Up);
471    ///
472    /// let ptr = rmut.transmute_into_raw::<u8>();
473    ///
474    /// unsafe {
475    ///     assert_eq!(*ptr, 2);
476    ///     *ptr = 3;
477    /// }
478    ///
479    /// assert_eq!(val, Direction::Down);
480    ///
481    /// #[repr(u8)]
482    /// #[derive(Debug, PartialEq)]
483    /// enum Direction {
484    ///     Left = 0,
485    ///     Right = 1,
486    ///     Up = 2,
487    ///     Down = 3,
488    /// }
489    ///
490    /// ```
491    #[inline(always)]
492    pub const fn transmute_into_raw<U>(self) -> *mut U {
493        self.ref_.as_ptr() as *mut U
494    }
495
496    /// Transmutes this `RMut<'a, T>` to a `&'a mut U`.
497    ///
498    /// # Safety
499    ///
500    /// Either of these must be the case:
501    ///
502    /// - [`U` is a prefix of `T`](#type-prefix-exp)
503    ///
504    /// - `RMut<'a, U>` was the original type of this `RMut<'a, T>`.
505    ///
506    /// # Example
507    ///
508    /// ```rust
509    /// use abi_stable::RMut;
510    ///
511    /// let mut val = 13u8;
512    /// let rmut = RMut::new(&mut val);
513    ///
514    /// assert_eq!(rmut.get(), &13);
515    ///
516    /// unsafe {
517    ///     *rmut.transmute_into_mut::<i8>() = -1;
518    /// }
519    ///
520    /// assert_eq!(val, 255);
521    ///
522    /// ```
523    #[inline(always)]
524    pub unsafe fn transmute_into_mut<U>(self) -> &'a mut U
525    where
526        U: 'a,
527    {
528        unsafe { &mut *(self.ref_.as_ptr() as *mut U) }
529    }
530
531    /// Transmutes this `RMut<'a, T>` to a `RMut<'a,U>`.
532    ///
533    /// # Safety
534    ///
535    /// Either of these must be the case:
536    ///
537    /// - [`U` is a prefix of `T`](#type-prefix-exp)
538    ///
539    /// - `RMut<'a, U>` was the original type of this `RMut<'a, T>`.
540    ///
541    /// # Example
542    ///
543    /// ```rust
544    /// use abi_stable::RMut;
545    ///
546    /// let mut val: [u32; 3] = [2, 3, 0];
547    /// let mut rmut = RMut::new(&mut val);
548    ///
549    /// unsafe {
550    ///     // safety:
551    ///     // it's sound to transmute mutable references of arrays into shorter arrays.
552    ///     //
553    ///     // The `.reborrow()` prevents the `rmut` from being consumed.
554    ///     compute_next(rmut.reborrow().transmute::<[u32; 2]>());
555    ///     assert_eq!(rmut.get_copy(), [3, 5, 0]);
556    ///
557    ///     compute_next(rmut.reborrow().transmute::<[u32; 2]>());
558    ///     assert_eq!(rmut.get_copy(), [5, 8, 0]);
559    ///
560    ///     // last use of `rmut`, so no need to reborrow
561    ///     compute_next(rmut.transmute::<[u32; 2]>());
562    /// }
563    ///
564    /// assert_eq!(val, [8, 13, 0]);
565    ///
566    /// fn compute_next(rmut: RMut<'_, [u32; 2]>) {
567    ///     let [v0, v1] = rmut.into_mut();
568    ///     let next = *v0 + *v1;
569    ///     *v0 = std::mem::replace(v1, next);
570    /// }
571    /// ```
572    #[inline(always)]
573    pub const unsafe fn transmute<U>(self) -> RMut<'a, U>
574    where
575        U: 'a,
576    {
577        unsafe { RMut::from_raw(self.ref_.as_ptr() as *mut U) }
578    }
579
580    /// Reborrows this `RMut<'a, T>` into an `RRef<'_, T>`
581    ///
582    /// # Example
583    ///
584    /// ```rust
585    /// use abi_stable::{RMut, RRef};
586    ///
587    /// let mut val = 77;
588    /// let rmut = RMut::new(&mut val);
589    ///
590    /// for _ in 0..10 {
591    ///     assertion(rmut.as_rref());
592    /// }
593    ///
594    /// fn assertion(rref: RRef<'_, u32>) {
595    ///     assert_eq!(rref.get_copy(), 77);
596    /// }
597    /// ```
598    #[inline(always)]
599    #[allow(clippy::needless_lifetimes)]
600    pub const fn as_rref<'r>(&'r self) -> RRef<'r, T> {
601        unsafe { RRef::from_raw(self.ref_.as_ptr()) }
602    }
603
604    /// Converts this `RMut<'a, T>` to an `RRef<'_, T>`
605    ///
606    /// # Example
607    ///
608    /// ```rust
609    /// use abi_stable::{RMut, RRef};
610    ///
611    /// let mut val = 0;
612    /// let rmut = RMut::new(&mut val);
613    ///
614    /// assertion(rmut.into_rref());
615    ///
616    /// fn assertion(rref: RRef<'_, u32>) {
617    ///     assert_eq!(rref.get_copy(), 0);
618    /// }
619    /// ```
620    #[inline(always)]
621    pub const fn into_rref(self) -> RRef<'a, T> {
622        unsafe { RRef::from_raw(self.ref_.as_ptr()) }
623    }
624}
625
626unsafe impl<'a, T> AsPtr for RMut<'a, T> {
627    #[inline(always)]
628    fn as_ptr(&self) -> *const T {
629        self.ref_.as_ptr() as *const T
630    }
631    #[inline(always)]
632    fn as_rref(&self) -> RRef<'_, T> {
633        unsafe { RRef::from_raw(self.ref_.as_ptr() as *const T) }
634    }
635}
636
637unsafe impl<'a, T> AsMutPtr for RMut<'a, T> {
638    #[inline(always)]
639    fn as_mut_ptr(&mut self) -> *mut T {
640        self.ref_.as_ptr()
641    }
642
643    #[inline(always)]
644    fn as_rmut(&mut self) -> RMut<'_, T> {
645        self.reborrow()
646    }
647}
648
649unsafe impl<'a, T> GetPointerKind for RMut<'a, T> {
650    type Kind = PK_MutReference;
651
652    type PtrTarget = T;
653}
654
655unsafe impl<'a, T, U> CanTransmuteElement<U> for RMut<'a, T>
656where
657    U: 'a,
658{
659    type TransmutedPtr = RMut<'a, U>;
660
661    #[inline(always)]
662    unsafe fn transmute_element_(self) -> Self::TransmutedPtr {
663        unsafe { self.transmute() }
664    }
665}
666
667#[cfg(test)]
668mod tests {
669    use super::*;
670
671    #[test]
672    fn construction_test() {
673        unsafe {
674            let val: *mut i32 = &mut 3;
675            let mut rmut = RMut::from_raw(val);
676            *rmut.get_mut() += 5;
677            assert_eq!(rmut.get_copy(), 8);
678        }
679        {
680            let val = &mut 3;
681            let mut rmut = RMut::new(val);
682            *rmut.get_mut() += 5;
683            assert_eq!(rmut.get_copy(), 8);
684        }
685    }
686
687    #[test]
688    fn access() {
689        let mut num = 5;
690        let mut mutref = RMut::new(&mut num);
691
692        assert_eq!(*mutref.get_mut(), 5);
693        *mutref.get_mut() = 21;
694
695        assert_eq!(*mutref.get(), 21);
696        assert_eq!(mutref.get_copy(), 21);
697        assert_eq!(*mutref.reborrow().into_ref(), 21);
698
699        *mutref.reborrow().into_mut() = 34;
700
701        unsafe {
702            assert_eq!(*mutref.as_ptr(), 34);
703
704            *mutref.as_mut_ptr() = 55;
705
706            assert_eq!(*mutref.reborrow().into_raw(), 55);
707            *mutref.reborrow().into_raw() = 89;
708        }
709        assert_eq!(num, 89);
710    }
711
712    #[test]
713    fn transmutes() {
714        let mut num = 0u8;
715
716        unsafe {
717            let ptr = RMut::new(&mut num).transmute_into_raw::<Enum>();
718            assert_eq!(*ptr, Enum::Foo);
719
720            ptr.write(Enum::Bar);
721            assert_eq!(*ptr, Enum::Bar);
722            assert_eq!(num, 1);
723        }
724        unsafe {
725            let mref = RMut::new(&mut num).transmute_into_mut::<Enum>();
726            assert_eq!(*mref, Enum::Bar);
727
728            *mref = Enum::Qux;
729            assert_eq!(*mref, Enum::Qux);
730            assert_eq!(num, 2);
731        }
732        unsafe {
733            let mut rmut = RMut::new(&mut num).transmute::<Enum>();
734            assert_eq!(rmut, RMut::new(&mut Enum::Qux));
735
736            *rmut.get_mut() = Enum::Foo;
737            assert_eq!(*rmut.get(), Enum::Foo);
738            assert_eq!(num, 0);
739        }
740        unsafe {
741            let mut rmut: RMut<'_, Enum> = RMut::new(&mut num).transmute_element_();
742            assert_eq!(rmut, RMut::new(&mut Enum::Foo));
743
744            *rmut.get_mut() = Enum::Bar;
745            assert_eq!(*rmut.get(), Enum::Bar);
746            assert_eq!(num, 1);
747        }
748    }
749
750    #[test]
751    fn as_rtype_test() {
752        let mut num = 0u8;
753        let mut rmut = RMut::new(&mut num);
754
755        assert_eq!(rmut.as_rref(), RRef::new(&0));
756        assert_eq!(rmut.reborrow().into_rref(), RRef::new(&0));
757
758        assert_eq!(rmut.as_rmut(), RMut::new(&mut 0));
759    }
760
761    #[derive(Debug, PartialEq)]
762    #[repr(u8)]
763    enum Enum {
764        Foo = 0,
765        Bar = 1,
766        Qux = 2,
767    }
768}