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, 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 no |
32 | /// unsoundness will arise from violating the safety invariants of the |
33 | /// destination type (and sometimes of the source type, too). |
34 | pub safety: bool, |
35 | |
36 | /// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid |
37 | /// instance of the destination type. |
38 | pub validity: bool, |
39 | } |
40 | |
41 | #[unstable (feature = "transmutability" , issue = "99571" )] |
42 | impl ConstParamTy for Assume {} |
43 | |
44 | impl Assume { |
45 | /// Do not assume that *you* have ensured any safety properties are met. |
46 | #[unstable (feature = "transmutability" , issue = "99571" )] |
47 | pub const NOTHING: Self = |
48 | Self { alignment: false, lifetimes: false, safety: false, validity: false }; |
49 | |
50 | /// Assume only that alignment conditions are met. |
51 | #[unstable (feature = "transmutability" , issue = "99571" )] |
52 | pub const ALIGNMENT: Self = Self { alignment: true, ..Self::NOTHING }; |
53 | |
54 | /// Assume only that lifetime conditions are met. |
55 | #[unstable (feature = "transmutability" , issue = "99571" )] |
56 | pub const LIFETIMES: Self = Self { lifetimes: true, ..Self::NOTHING }; |
57 | |
58 | /// Assume only that safety conditions are met. |
59 | #[unstable (feature = "transmutability" , issue = "99571" )] |
60 | pub const SAFETY: Self = Self { safety: true, ..Self::NOTHING }; |
61 | |
62 | /// Assume only that dynamically-satisfiable validity conditions are met. |
63 | #[unstable (feature = "transmutability" , issue = "99571" )] |
64 | pub const VALIDITY: Self = Self { validity: true, ..Self::NOTHING }; |
65 | |
66 | /// Assume both `self` and `other_assumptions`. |
67 | #[unstable (feature = "transmutability" , issue = "99571" )] |
68 | pub const fn and(self, other_assumptions: Self) -> Self { |
69 | Self { |
70 | alignment: self.alignment || other_assumptions.alignment, |
71 | lifetimes: self.lifetimes || other_assumptions.lifetimes, |
72 | safety: self.safety || other_assumptions.safety, |
73 | validity: self.validity || other_assumptions.validity, |
74 | } |
75 | } |
76 | |
77 | /// Assume `self`, excepting `other_assumptions`. |
78 | #[unstable (feature = "transmutability" , issue = "99571" )] |
79 | pub const fn but_not(self, other_assumptions: Self) -> Self { |
80 | Self { |
81 | alignment: self.alignment && !other_assumptions.alignment, |
82 | lifetimes: self.lifetimes && !other_assumptions.lifetimes, |
83 | safety: self.safety && !other_assumptions.safety, |
84 | validity: self.validity && !other_assumptions.validity, |
85 | } |
86 | } |
87 | } |
88 | |
89 | // FIXME(jswrenn): This const op is not actually usable. Why? |
90 | // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926 |
91 | #[unstable (feature = "transmutability" , issue = "99571" )] |
92 | impl core::ops::Add for Assume { |
93 | type Output = Assume; |
94 | |
95 | fn add(self, other_assumptions: Assume) -> Assume { |
96 | self.and(other_assumptions) |
97 | } |
98 | } |
99 | |
100 | // FIXME(jswrenn): This const op is not actually usable. Why? |
101 | // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926 |
102 | #[unstable (feature = "transmutability" , issue = "99571" )] |
103 | impl core::ops::Sub for Assume { |
104 | type Output = Assume; |
105 | |
106 | fn sub(self, other_assumptions: Assume) -> Assume { |
107 | self.but_not(other_assumptions) |
108 | } |
109 | } |
110 | |