11use  crate :: marker:: { ConstParamTy_ ,  UnsizedConstParamTy } ; 
22
3- /// Are values of a type  transmutable into values of another type?  
3+ /// Marks that `Src` is  transmutable into `Self`.  
44/// 
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. 
5+ /// # Implementation 
6+ /// 
7+ /// This trait cannot be implemented explicitly. It is implemented on-the-fly by 
8+ /// the compiler for all types `Src` and `Self` such that, given a set of safety 
9+ /// obligations on the programmer (see [`Assume`]), the compiler has proved that 
10+ /// the bits of a value of type `Src` can be soundly reinterpreted as a `Self`. 
11+ /// 
12+ /// Specifically, this trait models (and 
13+ /// [implements](BikeshedIntrinsicFrom::transmute)) the semantics of 
14+ /// transmute-via-union; i.e.: 
15+ /// 
16+ /// ```rust 
17+ /// pub unsafe fn transmute_via_union<Src, Dst>(src: Src) -> Dst { 
18+ ///     use core::mem::ManuallyDrop; 
19+ /// 
20+ ///     #[repr(C)] 
21+ ///     union Transmute<Src, Dst> { 
22+ ///         src: ManuallyDrop<Src>, 
23+ ///         dst: ManuallyDrop<Dst>, 
24+ ///     } 
25+ /// 
26+ ///     let transmute = Transmute { 
27+ ///         src: ManuallyDrop::new(src), 
28+ ///     }; 
29+ /// 
30+ ///     let dst = transmute.dst; 
31+ /// 
32+ ///     ManuallyDrop::into_inner(dst) 
33+ /// } 
34+ /// ``` 
35+ /// 
36+ /// Note that this construction supports some transmutations forbidden by 
37+ /// [`mem::transmute_copy`](super::transmute_copy); namely, transmutations that 
38+ /// extend the bits of `Src` with trailing padding to fill trailing 
39+ /// uninitialized bytes of `Self`; e.g.: 
40+ /// 
41+ /// ``` 
42+ /// #![feature(transmutability)] 
43+ /// 
44+ /// use core::mem::{Assume, BikeshedIntrinsicFrom}; 
45+ /// 
46+ /// let src = 42u8; // size = 1 
47+ /// 
48+ /// #[repr(C, align(2))] 
49+ /// struct Dst(u8); // size = 2 
50+ // 
51+ /// let _ = unsafe { <Dst as BikeshedIntrinsicFrom<u8, { Assume::SAFETY 
52+ ///     }>>::transmute(src) }; 
53+ /// ``` 
54+ /// 
55+ /// ## Portability 
56+ /// 
57+ /// Implementations of this trait do not provide any guarantee of portability 
58+ /// across toolchains, targets or compilations. This trait may be implemented 
59+ /// for certain combinations of `Src`, `Self` and `ASSUME` on some toolchains, 
60+ /// targets or compilations, but not others. For example, if the layouts of 
61+ /// `Src` or `Self` are non-deterministic, the presence or absence of an 
62+ /// implementation of this trait may also be non-deterministic. Even if `Src` 
63+ /// and `Self` have deterministic layouts (e.g., they are `repr(C)` structs), 
64+ /// Rust does not specify the alignments of its primitive integer types, and 
65+ /// layouts that involve these types may vary across toolchains, targets or 
66+ /// compilations. 
67+ /// 
68+ /// ## Stability 
69+ /// 
70+ /// Implementations of this trait do not provide any guarantee of SemVer 
71+ /// stability across the crate versions that define the `Src` and `Self` types. 
72+ /// If SemVer stability is crucial to your application, you must consult the 
73+ /// documentation of `Src` and `Self`s' defining crates. Note that the presence 
74+ /// of `repr(C)`, alone, does not carry a safety invariant of SemVer stability. 
75+ /// Furthermore, stability does not imply portability. For example, the size of 
76+ /// `usize` is stable, but not portable. 
877#[ unstable( feature = "transmutability" ,  issue = "99571" ) ]  
978#[ lang = "transmute_trait" ]  
1079#[ rustc_deny_explicit_impl( implement_via_object = false ) ]  
@@ -13,28 +82,96 @@ pub unsafe trait BikeshedIntrinsicFrom<Src, const ASSUME: Assume = { Assume::NOT
1382where 
1483    Src :  ?Sized , 
1584{ 
85+     /// Transmutes a `Src` value into a `Self`. 
86+      /// 
87+      /// # Safety 
88+      /// 
89+      /// The safety obligations of the caller depend on the value of `ASSUME`: 
90+      /// - If [`ASSUME.alignment`](Assume::alignment), the caller must guarantee 
91+      ///   that the addresses of references in the returned `Self` satisfy the 
92+      ///   alignment requirements of their referent types. 
93+      /// - If [`ASSUME.lifetimes`](Assume::lifetimes), the caller must guarantee 
94+      ///   that references in the returned `Self` will not outlive their 
95+      ///   referents. 
96+      /// - If [`ASSUME.safety`](Assume::safety), the returned value might not 
97+      ///   satisfy the library safety invariants of `Self`, and the caller must 
98+      ///   guarantee that undefined behavior does not arise from uses of the 
99+      ///   returned value. 
100+      /// - If [`ASSUME.validity`](Assume::validity), the caller must guarantee 
101+      ///   that `src` is a bit-valid instance of `Self`. 
102+      /// 
103+      /// When satisfying the above obligations (if any), the caller must *not* 
104+      /// assume that this trait provides any inherent guarantee of layout 
105+      /// [portability](#portability) or [stability](#stability). 
106+      unsafe  fn  transmute ( src :  Src )  -> Self 
107+     where 
108+         Src :  Sized , 
109+         Self :  Sized , 
110+     { 
111+         use  super :: ManuallyDrop ; 
112+ 
113+         #[ repr( C ) ]  
114+         union  Transmute < Src ,  Dst >  { 
115+             src :  ManuallyDrop < Src > , 
116+             dst :  ManuallyDrop < Dst > , 
117+         } 
118+ 
119+         let  transmute = Transmute  {  src :  ManuallyDrop :: new ( src)  } ; 
120+ 
121+         // SAFETY: It is safe to reinterpret the bits of `src` as a value of 
122+         // type `Self`, because, by combination of invariant on this trait and 
123+         // contract on the caller, `src` has been proven to satisfy both the 
124+         // language and library invariants of `Self`. For all invariants not 
125+         // `ASSUME`'d by the caller, the safety obligation is supplied by the 
126+         // compiler. Conversely, for all invariants `ASSUME`'d by the caller, 
127+         // the safety obligation is supplied by contract on the caller. 
128+         let  dst = unsafe  {  transmute. dst  } ; 
129+ 
130+         ManuallyDrop :: into_inner ( dst) 
131+     } 
16132} 
17133
18- /// What transmutation safety conditions shall the compiler assume that *you* are checking? 
134+ /// Configurable proof assumptions of [`BikeshedIntrinsicFrom`]. 
135+ /// 
136+ /// When `false`, the respective proof obligation belongs to the compiler. When 
137+ /// `true`, the onus of the safety proof belongs to the programmer. 
138+ /// [`BikeshedIntrinsicFrom`]. 
19139#[ unstable( feature = "transmutability" ,  issue = "99571" ) ]  
20140#[ lang = "transmute_opts" ]  
21141#[ derive( PartialEq ,  Eq ,  Clone ,  Copy ,  Debug ) ]  
22142pub  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. 
143+     /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for 
144+      /// transmutations that might violate the the alignment requirements of 
145+      /// references. 
146+      /// 
147+      /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured 
148+      /// that that references in the transmuted value satisfy the alignment 
149+      /// requirements of their referent types. 
25150     pub  alignment :  bool , 
26151
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. 
152+     /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for 
153+      /// transmutations that extend the lifetimes of references. 
154+      /// 
155+      /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured 
156+      /// that that references in the transmuted value do not outlive their 
157+      /// referents. 
29158     pub  lifetimes :  bool , 
30159
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). 
160+     /// When `false`,  [`BikeshedIntrinsicFrom`] is not implemented for 
161+      /// transmutations that might violate the library safety invariants of the 
162+      /// return type. 
163+      /// 
164+      /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured 
165+      /// that undefined behavior does not arise from using the returned value. 
34166     pub  safety :  bool , 
35167
36-     /// When `true`, the compiler assumes that *you* are ensuring that the source type is actually a valid 
37-      /// instance of the destination type. 
168+     /// When `false`, [`BikeshedIntrinsicFrom`] is not implemented for 
169+      /// transmutations that might violate the language-level bit-validity 
170+      /// invariant of the return type. 
171+      /// 
172+      /// When `true`, [`BikeshedIntrinsicFrom`] assumes that *you* have ensured 
173+      /// that the value being transmuted is a bit-valid instance of the return 
174+      /// type. 
38175     pub  validity :  bool , 
39176} 
40177
0 commit comments