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 `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<T, U> {
22+ /// src: ManuallyDrop<T>,
23+ /// dst: ManuallyDrop<U>,
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 trailing padding of `Src` to fill `Dst`.
39+ ///
40+ /// ## Portability
41+ ///
42+ /// Implementations of this trait do provide any guarantee of portability across
43+ /// toolchains or compilations. This trait may be implemented for certain
44+ /// combinations of `Src`, `Self` and `ASSUME` on some toolchains, but not
45+ /// others. For example, if the layouts of `Src` or `Self` are
46+ /// non-deterministic, the presence or absence of an implementation of this
47+ /// trait may also be non-deterministic. Even if `Src` and `Self` have
48+ /// deterministic layouts (e.g., they are `repr(C)` structs), Rust does not
49+ /// specify the alignments of its primitive integer types, and layouts that
50+ /// involve these types may vary across toolchains.
51+ ///
52+ /// ## Stability
53+ ///
54+ /// Implementations of this trait do not provide any guarantee of SemVer
55+ /// stability across the crate versions that define the `Src` and `Self` types.
56+ /// If SemVer stability is crucial to your application, you must consult the
57+ /// documentation of `Src` and `Self`s' defining crates. Note that the presence
58+ /// of `repr(C)`, alone, does not carry a safety invariant of SemVer stability.
59+ /// Furthermore, stability does not imply portability. For example, the size of
60+ /// `usize` is stable, but not portable.
861#[ unstable( feature = "transmutability" , issue = "99571" ) ]
962#[ lang = "transmute_trait" ]
1063#[ rustc_deny_explicit_impl( implement_via_object = false ) ]
@@ -13,6 +66,53 @@ pub unsafe trait BikeshedIntrinsicFrom<Src, const ASSUME: Assume = { Assume::NOT
1366where
1467 Src : ?Sized ,
1568{
69+ /// Transmutes a `Src` value into a `Self`.
70+ ///
71+ /// # Safety
72+ ///
73+ /// The safety obligations of the caller depend on the value of `ASSUME`:
74+ /// - If [`ASSUME.alignment`](Assume::alignment), the caller must prove that
75+ /// all references in `src` (including `src` itself, if `Src` is a
76+ /// reference type) have well-aligned referents upon transmutation into
77+ /// `Self`.
78+ /// - If [`ASSUME.lifetimes`](Assume::lifetimes), the caller must prove that
79+ /// all references in `src` (including `src` itself, if `Src` is a
80+ /// reference type) have referents that live as long as `Self`.
81+ /// - If [`ASSUME.safety`](Assume::safety), the caller must prove that the
82+ /// value `src` transmuted into `Self` satisfies all library safety
83+ /// invariants of `Self`.
84+ /// - If [`ASSUME.validity`](Assume::validity), the caller must prove that
85+ /// `src` is a bit-valid instance of `Self`.
86+ ///
87+ /// When satisfying the above obligations (if any), the caller must *not*
88+ /// assume that this trait provides any inherent guarantee of layout
89+ /// [portability](#portability) or [stability](#stability).
90+ unsafe fn transmute ( src : Src ) -> Self
91+ where
92+ Src : Sized ,
93+ Self : Sized ,
94+ {
95+ use super :: ManuallyDrop ;
96+
97+ #[ repr( C ) ]
98+ union Transmute < T , U > {
99+ src : ManuallyDrop < T > ,
100+ dst : ManuallyDrop < U > ,
101+ }
102+
103+ let transmute = Transmute { src : ManuallyDrop :: new ( src) } ;
104+
105+ // SAFETY: It is safe to reinterpret the bits of `src` as a value of
106+ // type `Self`, because, by combination of invariant on this trait and
107+ // contract on the caller, `src` has been proven to satisfy both the
108+ // language and library invariants of `Self`. For all invariants not
109+ // `ASSUME`'d by the caller, the safety obligation is supplied by the
110+ // compiler. Conversely, for all invariants `ASSUME`'d by the caller,
111+ // the safety obligation is supplied by contract on the caller.
112+ let dst = unsafe { transmute. dst } ;
113+
114+ ManuallyDrop :: into_inner ( dst)
115+ }
16116}
17117
18118/// What transmutation safety conditions shall the compiler assume that *you* are checking?
0 commit comments