1
1
use crate :: marker:: { ConstParamTy_ , UnsizedConstParamTy } ;
2
2
3
- /// Are values of a type transmutable into values of another type?
3
+ /// Marks that `Src` is transmutable into `Self`.
4
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.
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.
8
61
#[ unstable( feature = "transmutability" , issue = "99571" ) ]
9
62
#[ lang = "transmute_trait" ]
10
63
#[ rustc_deny_explicit_impl( implement_via_object = false ) ]
@@ -13,6 +66,53 @@ pub unsafe trait BikeshedIntrinsicFrom<Src, const ASSUME: Assume = { Assume::NOT
13
66
where
14
67
Src : ?Sized ,
15
68
{
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
+ }
16
116
}
17
117
18
118
/// What transmutation safety conditions shall the compiler assume that *you* are checking?
0 commit comments