@@ -13,8 +13,8 @@ use core::{
1313} ;
1414
1515use crate :: {
16- pointer:: { cast, invariant:: * } ,
1716 FromBytes , Immutable , IntoBytes , Unalign ,
17+ pointer:: { cast, invariant:: * } ,
1818} ;
1919
2020/// Transmutations which are sound to attempt, conditional on validating the bit
@@ -46,15 +46,14 @@ use crate::{
4646/// - So long as `dst` is active, no mutation of `dst`'s referent is allowed
4747/// except via `dst` itself
4848/// - The set of `DV`-valid referents of `dst` is a superset of the set of
49- /// `SV`-valid referents of `src` (NOTE: this condition effectively bans
50- /// shrinking or overwriting transmutes, which cannot satisfy this
51- /// condition)
49+ /// (the prefixes of) `SV`-valid referents of `src`. The "prefix" caveat is
50+ /// necessary since this may be a shrinking transmute – ie, `dst` addresses
51+ /// a smaller referent than `src`.
5252/// - Reverse transmutation: Either of the following hold:
5353/// - `dst` does not permit mutation of its referent
54- /// - The set of `DV`-valid referents of `dst` is a subset of the set of
55- /// `SV`-valid referents of `src` (NOTE: this condition effectively bans
56- /// shrinking or overwriting transmutes, which cannot satisfy this
57- /// condition)
54+ /// - `<Dst as SizeEq<Src>>::CastFrom: CastExact`, and the set of `DV`-valid
55+ /// referents of `dst` is a subset of the set of `SV`-valid referents of
56+ /// `src`
5857/// - No safe code, given access to `src` and `dst`, can cause undefined
5958/// behavior: Any of the following hold:
6059/// - `A` is `Exclusive`
@@ -94,18 +93,21 @@ use crate::{
9493/// as an `SV`-valid `Src`. It is guaranteed to remain so, as either of the
9594/// following hold:
9695/// - `dst` does not permit mutation of its referent.
97- /// - The set of `DV`-valid referents of `dst` is a subset of the set of
98- /// `SV`-valid referents of `src`. Thus, any value written via `dst` is
99- /// guaranteed to be an `SV`-valid referent of `src`.
96+ /// - `<Dst as SizeEq<Src>>::CastFrom: CastExact`, and the set of `DV`-valid
97+ /// referents of `dst` is a subset of the set of `SV`-valid referents of
98+ /// `src`. By `CastExact`, `src` and `dst` address the same number of bytes.
99+ /// Thus, any value written via `dst` is guaranteed to be an `SV`-valid
100+ /// referent of `src`.
100101///
101102/// Fourth, `dst`'s validity is satisfied. It is a given of this proof that the
102103/// referent is `DV`-valid for `Dst`. It is guaranteed to remain so, as either
103104/// of the following hold:
104105/// - So long as `dst` is active, no mutation of the referent is allowed except
105106/// via `dst` itself.
106107/// - The set of `DV`-valid referents of `dst` is a superset of the set of
107- /// `SV`-valid referents of `src`. Thus, any value written via `src` is
108- /// guaranteed to be a `DV`-valid referent of `dst`.
108+ /// (the prefixes of) `SV`-valid referents of `src`. Thus, (the prefix of) any
109+ /// value written via `src` is guaranteed to be a `DV`-valid referent of
110+ /// `dst`.
109111pub unsafe trait TryTransmuteFromPtr < Src : ?Sized , A : Aliasing , SV : Validity , DV : Validity , R > :
110112 SizeEq < Src >
111113{
@@ -123,14 +125,14 @@ pub enum BecauseMutationCompatible {}
123125// exists, no mutation is permitted except via that `Ptr`
124126// - Aliasing is `Shared`, `Src: Immutable`, and `Dst: Immutable`, in which
125127// case no mutation is possible via either `Ptr`
126- // - Since the underlying cast is performed using `<Dst as SizeEq<Src>>
127- // ::CastFrom::project`, `dst` addresses the same bytes as `src`. By `Dst:
128- // TransmuteFrom<Src, SV, DV>`, the set of `DV`-valid referents of `dst` is a
129- // supserset of the set of `SV`-valid referents of `src`.
128+ // - By `Dst: TransmuteFrom<Src, SV, DV>`, the set of `DV`-valid referents of
129+ // `dst` is a supserset of the set of (the prefixes of) `SV`-valid referents
130+ // of `src`.
130131// - Reverse transmutation: Since the underlying cast is performed using `<Dst
131- // as SizeEq<Src>>::CastFrom::project`, `dst` addresses the same bytes as
132- // `src`. By `Src: TransmuteFrom<Dst, DV, SV>`, the set of `DV`-valid
133- // referents of `dst` is a subset of the set of `SV`-valid referents of `src`.
132+ // as SizeEq<Src>>::CastFrom::project`, and since `Dst::CastFrom: CastExact`,
133+ // `dst` addresses the same bytes as `src`. By `Src: TransmuteFrom<Dst, DV,
134+ // SV>`, the set of `DV`-valid referents of `dst` is a subset of the set of
135+ // `SV`-valid referents of `src`.
134136// - No safe code, given access to `src` and `dst`, can cause undefined
135137// behavior: By `Dst: MutationCompatible<Src, A, SV, DV, _>`, at least one of
136138// the following holds:
@@ -146,6 +148,7 @@ where
146148 DV : Validity ,
147149 Src : TransmuteFrom < Dst , DV , SV > + ?Sized ,
148150 Dst : MutationCompatible < Src , A , SV , DV , R > + SizeEq < Src > + ?Sized ,
151+ Dst :: CastFrom : cast:: CastExact < Src , Dst > ,
149152{
150153}
151154
@@ -267,6 +270,12 @@ where
267270{
268271}
269272
273+ // TODO: We need to update the invariant of `TransmuteFrom` in order to make the
274+ // "reverse transmutation" impl of `TryTransmuteFromPtr` sound – currently, it
275+ // says that `Dst: TransmuteFrom<Src>` guarantees transmutation *even in the
276+ // case of a shrinking transmute*, but that's not currently guaranteed by
277+ // `TransmuteFrom`'s safety invariant.
278+
270279/// Denotes that any `SV`-valid `Src` may soundly be transmuted into a
271280/// `DV`-valid `Self`.
272281///
@@ -292,12 +301,12 @@ pub unsafe trait TransmuteFrom<Src: ?Sized, SV, DV> {}
292301///
293302/// `SizeEq` on its own conveys no safety guarantee. Any safety guarantees come
294303/// from the safety invariants on the associated [`CastFrom`] type, specifically
295- /// the [`CastExact `] bound.
304+ /// the [`Cast `] bound.
296305///
297306/// [`CastFrom`]: SizeEq::CastFrom
298- /// [`CastExact `]: cast::CastExact
307+ /// [`Cast `]: cast::Cast
299308pub trait SizeEq < Src : ?Sized > {
300- type CastFrom : cast:: CastExact < Src , Self > ;
309+ type CastFrom : cast:: Cast < Src , Self > ;
301310}
302311
303312impl < T : ?Sized > SizeEq < T > for T {
0 commit comments