]> git.lizzy.rs Git - rust.git/blob - library/core/src/mem/transmutability.rs
Merge commit '2bb3996244cf1b89878da9e39841e9f6bf061602' into sync_cg_clif-2022-12-14
[rust.git] / library / core / src / mem / transmutability.rs
1 /// Are values of a type transmutable into values of another type?
2 ///
3 /// This trait is implemented on-the-fly by the compiler for types `Src` and `Self` when the bits of
4 /// any value of type `Self` are safely transmutable into a value of type `Dst`, in a given `Context`,
5 /// notwithstanding whatever safety checks you have asked the compiler to [`Assume`] are satisfied.
6 #[unstable(feature = "transmutability", issue = "99571")]
7 #[lang = "transmute_trait"]
8 #[rustc_on_unimplemented(
9     message = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`.",
10     label = "`{Src}` cannot be safely transmuted into `{Self}` in the defining scope of `{Context}`."
11 )]
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 impl Assume {
41     /// Do not assume that *you* have ensured any safety properties are met.
42     #[unstable(feature = "transmutability", issue = "99571")]
43     pub const NOTHING: Self =
44         Self { alignment: false, lifetimes: false, safety: false, validity: false };
45
46     /// Assume only that alignment conditions are met.
47     #[unstable(feature = "transmutability", issue = "99571")]
48     pub const ALIGNMENT: Self = Self { alignment: true, ..Self::NOTHING };
49
50     /// Assume only that lifetime conditions are met.
51     #[unstable(feature = "transmutability", issue = "99571")]
52     pub const LIFETIMES: Self = Self { lifetimes: true, ..Self::NOTHING };
53
54     /// Assume only that safety conditions are met.
55     #[unstable(feature = "transmutability", issue = "99571")]
56     pub const SAFETY: Self = Self { safety: true, ..Self::NOTHING };
57
58     /// Assume only that dynamically-satisfiable validity conditions are met.
59     #[unstable(feature = "transmutability", issue = "99571")]
60     pub const VALIDITY: Self = Self { validity: true, ..Self::NOTHING };
61
62     /// Assume both `self` and `other_assumptions`.
63     #[unstable(feature = "transmutability", issue = "99571")]
64     pub const fn and(self, other_assumptions: Self) -> Self {
65         Self {
66             alignment: self.alignment || other_assumptions.alignment,
67             lifetimes: self.lifetimes || other_assumptions.lifetimes,
68             safety: self.safety || other_assumptions.safety,
69             validity: self.validity || other_assumptions.validity,
70         }
71     }
72
73     /// Assume `self`, excepting `other_assumptions`.
74     #[unstable(feature = "transmutability", issue = "99571")]
75     pub const fn but_not(self, other_assumptions: Self) -> Self {
76         Self {
77             alignment: self.alignment && !other_assumptions.alignment,
78             lifetimes: self.lifetimes && !other_assumptions.lifetimes,
79             safety: self.safety && !other_assumptions.safety,
80             validity: self.validity && !other_assumptions.validity,
81         }
82     }
83 }
84
85 // FIXME(jswrenn): This const op is not actually usable. Why?
86 // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926
87 #[unstable(feature = "transmutability", issue = "99571")]
88 #[rustc_const_unstable(feature = "transmutability", issue = "99571")]
89 impl const core::ops::Add for Assume {
90     type Output = Assume;
91
92     fn add(self, other_assumptions: Assume) -> Assume {
93         self.and(other_assumptions)
94     }
95 }
96
97 // FIXME(jswrenn): This const op is not actually usable. Why?
98 // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926
99 #[unstable(feature = "transmutability", issue = "99571")]
100 #[rustc_const_unstable(feature = "transmutability", issue = "99571")]
101 impl const core::ops::Sub for Assume {
102     type Output = Assume;
103
104     fn sub(self, other_assumptions: Assume) -> Assume {
105         self.but_not(other_assumptions)
106     }
107 }