1 | use crate::marker::ConstParamTy; |
2 | |
3 | /// Are values of a type transmutable into values of another type? |
4 | /// |
5 | /// This trait is implemented on-the-fly by the compiler for types `Src` and `Self` when the bits of |
6 | /// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`, |
7 | /// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied. |
8 | #[unstable (feature = "transmutability" , issue = "99571" )] |
9 | #[lang = "transmute_trait" ] |
10 | #[rustc_deny_explicit_impl (implement_via_object = false)] |
11 | #[rustc_coinductive ] |
12 | pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }> |
13 | where |
14 | Src: ?Sized, |
15 | { |
16 | } |
17 | |
18 | /// What transmutation safety conditions shall the compiler assume that *you* are checking? |
19 | #[unstable (feature = "transmutability" , issue = "99571" )] |
20 | #[lang = "transmute_opts" ] |
21 | #[derive (PartialEq, Eq, Clone, Copy, Debug)] |
22 | pub struct Assume { |
23 | /// When `true`, the compiler assumes that *you* are ensuring (either dynamically or statically) that |
24 | /// destination referents do not have stricter alignment requirements than source referents. |
25 | pub alignment: bool, |
26 | |
27 | /// When `true`, the compiler assume that *you* are ensuring that lifetimes are not extended in a manner |
28 | /// that violates Rust's memory model. |
29 | pub lifetimes: bool, |
30 | |
31 | /// When `true`, the compiler assumes that *you* have ensured that it is safe for you to violate the |
32 | /// type and field privacy of the destination type (and sometimes of the source type, too). |
33 | pub safety: bool, |
34 | |
35 | /// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid |
36 | /// instance of the destination type. |
37 | pub validity: bool, |
38 | } |
39 | |
40 | #[unstable (feature = "transmutability" , issue = "99571" )] |
41 | impl ConstParamTy for Assume {} |
42 | |
43 | impl Assume { |
44 | /// Do not assume that *you* have ensured any safety properties are met. |
45 | #[unstable (feature = "transmutability" , issue = "99571" )] |
46 | pub const NOTHING: Self = |
47 | Self { alignment: false, lifetimes: false, safety: false, validity: false }; |
48 | |
49 | /// Assume only that alignment conditions are met. |
50 | #[unstable (feature = "transmutability" , issue = "99571" )] |
51 | pub const ALIGNMENT: Self = Self { alignment: true, ..Self::NOTHING }; |
52 | |
53 | /// Assume only that lifetime conditions are met. |
54 | #[unstable (feature = "transmutability" , issue = "99571" )] |
55 | pub const LIFETIMES: Self = Self { lifetimes: true, ..Self::NOTHING }; |
56 | |
57 | /// Assume only that safety conditions are met. |
58 | #[unstable (feature = "transmutability" , issue = "99571" )] |
59 | pub const SAFETY: Self = Self { safety: true, ..Self::NOTHING }; |
60 | |
61 | /// Assume only that dynamically-satisfiable validity conditions are met. |
62 | #[unstable (feature = "transmutability" , issue = "99571" )] |
63 | pub const VALIDITY: Self = Self { validity: true, ..Self::NOTHING }; |
64 | |
65 | /// Assume both `self` and `other_assumptions`. |
66 | #[unstable (feature = "transmutability" , issue = "99571" )] |
67 | pub const fn and(self, other_assumptions: Self) -> Self { |
68 | Self { |
69 | alignment: self.alignment || other_assumptions.alignment, |
70 | lifetimes: self.lifetimes || other_assumptions.lifetimes, |
71 | safety: self.safety || other_assumptions.safety, |
72 | validity: self.validity || other_assumptions.validity, |
73 | } |
74 | } |
75 | |
76 | /// Assume `self`, excepting `other_assumptions`. |
77 | #[unstable (feature = "transmutability" , issue = "99571" )] |
78 | pub const fn but_not(self, other_assumptions: Self) -> Self { |
79 | Self { |
80 | alignment: self.alignment && !other_assumptions.alignment, |
81 | lifetimes: self.lifetimes && !other_assumptions.lifetimes, |
82 | safety: self.safety && !other_assumptions.safety, |
83 | validity: self.validity && !other_assumptions.validity, |
84 | } |
85 | } |
86 | } |
87 | |
88 | // FIXME(jswrenn): This const op is not actually usable. Why? |
89 | // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926 |
90 | #[unstable (feature = "transmutability" , issue = "99571" )] |
91 | impl core::ops::Add for Assume { |
92 | type Output = Assume; |
93 | |
94 | fn add(self, other_assumptions: Assume) -> Assume { |
95 | self.and(other_assumptions) |
96 | } |
97 | } |
98 | |
99 | // FIXME(jswrenn): This const op is not actually usable. Why? |
100 | // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926 |
101 | #[unstable (feature = "transmutability" , issue = "99571" )] |
102 | impl core::ops::Sub for Assume { |
103 | type Output = Assume; |
104 | |
105 | fn sub(self, other_assumptions: Assume) -> Assume { |
106 | self.but_not(other_assumptions) |
107 | } |
108 | } |
109 | |