/rust/registry/src/index.crates.io-6f17d22bba15001f/yoke-0.7.5/src/macro_impls.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // This file is part of ICU4X. For terms of use, please see the file |
2 | | // called LICENSE at the top level of the ICU4X source tree |
3 | | // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). |
4 | | |
5 | | // In this case consistency between impls is more important |
6 | | // than using pointer casts |
7 | | #![allow(clippy::transmute_ptr_to_ptr)] |
8 | | |
9 | | use crate::Yokeable; |
10 | | use core::{ |
11 | | mem::{self, ManuallyDrop}, |
12 | | ptr, |
13 | | }; |
14 | | |
15 | | macro_rules! copy_yoke_impl { |
16 | | () => { |
17 | | #[inline] |
18 | 0 | fn transform(&self) -> &Self::Output { |
19 | 0 | self |
20 | 0 | } Unexecuted instantiation: <() as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <u8 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <u16 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <u32 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <u64 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <u128 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <usize as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <i8 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <i16 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <i32 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <i64 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <i128 as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <isize as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <char as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <bool as yoke::yokeable::Yokeable>::transform |
21 | | #[inline] |
22 | 0 | fn transform_owned(self) -> Self::Output { |
23 | 0 | self |
24 | 0 | } Unexecuted instantiation: <() as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <u8 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <u16 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <u32 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <u64 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <u128 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <usize as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <i8 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <i16 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <i32 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <i64 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <i128 as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <isize as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <char as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <bool as yoke::yokeable::Yokeable>::transform_owned |
25 | | #[inline] |
26 | 0 | unsafe fn make(this: Self::Output) -> Self { |
27 | 0 | this |
28 | 0 | } Unexecuted instantiation: <() as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <u8 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <u16 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <u32 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <u64 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <u128 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <usize as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <i8 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <i16 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <i32 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <i64 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <i128 as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <isize as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <char as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <bool as yoke::yokeable::Yokeable>::make |
29 | | #[inline] |
30 | 0 | fn transform_mut<F>(&'a mut self, f: F) |
31 | 0 | where |
32 | 0 | F: 'static + for<'b> FnOnce(&'b mut Self::Output), |
33 | 0 | { |
34 | 0 | f(self) |
35 | 0 | } Unexecuted instantiation: <() as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <u8 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <u16 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <u32 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <u64 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <u128 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <usize as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <i8 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <i16 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <i32 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <i64 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <i128 as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <isize as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <char as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <bool as yoke::yokeable::Yokeable>::transform_mut::<_> |
36 | | }; |
37 | | } |
38 | | macro_rules! impl_copy_type { |
39 | | ($ty:ty) => { |
40 | | // Safety: all the types that this macro is used to generate impls of Yokeable for do not |
41 | | // borrow any memory. |
42 | | unsafe impl<'a> Yokeable<'a> for $ty { |
43 | | type Output = Self; |
44 | | copy_yoke_impl!(); |
45 | | } |
46 | | }; |
47 | | } |
48 | | |
49 | | impl_copy_type!(()); |
50 | | impl_copy_type!(u8); |
51 | | impl_copy_type!(u16); |
52 | | impl_copy_type!(u32); |
53 | | impl_copy_type!(u64); |
54 | | impl_copy_type!(u128); |
55 | | impl_copy_type!(usize); |
56 | | impl_copy_type!(i8); |
57 | | impl_copy_type!(i16); |
58 | | impl_copy_type!(i32); |
59 | | impl_copy_type!(i64); |
60 | | impl_copy_type!(i128); |
61 | | impl_copy_type!(isize); |
62 | | impl_copy_type!(char); |
63 | | impl_copy_type!(bool); |
64 | | |
65 | | // This is for when we're implementing Yoke on a complex type such that it's not |
66 | | // obvious to the compiler that the lifetime is covariant |
67 | | // |
68 | | // Safety: the caller of this macro must ensure that `Self` is indeed covariant in 'a. |
69 | | macro_rules! unsafe_complex_yoke_impl { |
70 | | () => { |
71 | 0 | fn transform(&'a self) -> &'a Self::Output { |
72 | 0 | // Safety: equivalent to casting the lifetime. Macro caller ensures covariance. |
73 | 0 | unsafe { mem::transmute(self) } |
74 | 0 | } Unexecuted instantiation: <core::option::Option<_> as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <(_, _) as yoke::yokeable::Yokeable>::transform Unexecuted instantiation: <[_; _] as yoke::yokeable::Yokeable>::transform |
75 | | |
76 | 0 | fn transform_owned(self) -> Self::Output { |
77 | 0 | debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>()); |
78 | | // Safety: equivalent to casting the lifetime. Macro caller ensures covariance. |
79 | | unsafe { |
80 | 0 | let ptr: *const Self::Output = (&self as *const Self).cast(); |
81 | 0 | let _ = ManuallyDrop::new(self); |
82 | 0 | ptr::read(ptr) |
83 | 0 | } |
84 | 0 | } Unexecuted instantiation: <core::option::Option<_> as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <(_, _) as yoke::yokeable::Yokeable>::transform_owned Unexecuted instantiation: <[_; _] as yoke::yokeable::Yokeable>::transform_owned |
85 | | |
86 | 0 | unsafe fn make(from: Self::Output) -> Self { |
87 | 0 | debug_assert!(mem::size_of::<Self::Output>() == mem::size_of::<Self>()); |
88 | 0 | let ptr: *const Self = (&from as *const Self::Output).cast(); |
89 | 0 | let _ = ManuallyDrop::new(from); |
90 | 0 | // Safety: `ptr` is certainly valid, aligned and points to a properly initialized value, as |
91 | 0 | // it comes from a value that was moved into a ManuallyDrop. |
92 | 0 | unsafe { ptr::read(ptr) } |
93 | 0 | } Unexecuted instantiation: <core::option::Option<_> as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <(_, _) as yoke::yokeable::Yokeable>::make Unexecuted instantiation: <[_; _] as yoke::yokeable::Yokeable>::make |
94 | | |
95 | 0 | fn transform_mut<F>(&'a mut self, f: F) |
96 | 0 | where |
97 | 0 | F: 'static + for<'b> FnOnce(&'b mut Self::Output), |
98 | 0 | { |
99 | 0 | // Cast away the lifetime of Self |
100 | 0 | // Safety: this is equivalent to f(transmute(self)), and the documentation of the trait |
101 | 0 | // method explains why doing so is sound. |
102 | 0 | unsafe { f(mem::transmute::<&'a mut Self, &'a mut Self::Output>(self)) } |
103 | 0 | } Unexecuted instantiation: <core::option::Option<_> as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <(_, _) as yoke::yokeable::Yokeable>::transform_mut::<_> Unexecuted instantiation: <[_; _] as yoke::yokeable::Yokeable>::transform_mut::<_> |
104 | | }; |
105 | | } |
106 | | |
107 | | // Safety: since T implements Yokeable<'a>, Option<T<'b>> must be covariant on 'b or the Yokeable |
108 | | // implementation on T would be unsound. |
109 | | unsafe impl<'a, T: 'static + for<'b> Yokeable<'b>> Yokeable<'a> for Option<T> { |
110 | | type Output = Option<<T as Yokeable<'a>>::Output>; |
111 | | unsafe_complex_yoke_impl!(); |
112 | | } |
113 | | |
114 | | // Safety: since T1, T2 implement Yokeable<'a>, (T1<'b>, T2<'b>) must be covariant on 'b or the Yokeable |
115 | | // implementation on T would be unsound. |
116 | | unsafe impl<'a, T1: 'static + for<'b> Yokeable<'b>, T2: 'static + for<'b> Yokeable<'b>> Yokeable<'a> |
117 | | for (T1, T2) |
118 | | { |
119 | | type Output = (<T1 as Yokeable<'a>>::Output, <T2 as Yokeable<'a>>::Output); |
120 | | unsafe_complex_yoke_impl!(); |
121 | | } |
122 | | |
123 | | // Safety: since T implements Yokeable<'a>, [T<'b>; N] must be covariant on 'b or the Yokeable |
124 | | // implementation on T would be unsound. |
125 | | unsafe impl<'a, T: 'static + for<'b> Yokeable<'b>, const N: usize> Yokeable<'a> for [T; N] { |
126 | | type Output = [<T as Yokeable<'a>>::Output; N]; |
127 | | unsafe_complex_yoke_impl!(); |
128 | | } |