@@ -35,7 +35,7 @@ use crate::{
3535///
3636/// Given `src: Ptr<'a, Src, (A, _, SV)>`, if the referent of `src` is
3737/// `DV`-valid for `Dst`, then it is sound to transmute `src` into `dst: Ptr<'a,
38- /// Dst, (A, Unaligned, DV)>` by preserving pointer address and metadata .
38+ /// Dst, (A, Unaligned, DV)>` using `<Dst as SizeEq<Src>>::CastFrom::project` .
3939///
4040/// ## Pre-conditions
4141///
@@ -49,7 +49,10 @@ use crate::{
4949/// `Src`s
5050/// - Reverse transmutation: Either of the following hold:
5151/// - `dst` does not permit mutation of its referent
52- /// - The set of `DV`-valid `Dst`s is a subset of the set of `SV`-valid `Src`s
52+ /// - The set of `DV`-valid referents of `dst` is a subset of the set of
53+ /// `SV`-valid referents of `src` (NOTE: this condition effectively bans
54+ /// shrinking or overwriting transmutes, which cannot satisfy this
55+ /// condition)
5356/// - No safe code, given access to `src` and `dst`, can cause undefined
5457/// behavior: Any of the following hold:
5558/// - `A` is `Exclusive`
@@ -64,30 +67,17 @@ use crate::{
6467/// - `src`'s referent is `DV`-valid for `Dst`
6568/// - `Dst: SizeEq<Src>`
6669///
67- /// We are trying to prove that it is sound to perform a pointer address- and
68- /// metadata-preserving transmute from `src` to a `dst: Ptr<'a, Dst, (A,
70+ /// We are trying to prove that it is sound to cast using `<Dst as
71+ /// SizeEq<Src>>::CastFrom::project` from `src` to a `dst: Ptr<'a, Dst, (A,
6972/// Unaligned, DV)>`. We need to prove that such a transmute does not violate
7073/// any of `src`'s invariants, and that it satisfies all invariants of the
7174/// destination `Ptr` type.
7275///
73- /// First, all of `src`'s `PtrInner` invariants are upheld. `src`'s address and
74- /// metadata are unchanged, so:
75- /// - If its referent is not zero sized, then it still has valid provenance for
76- /// its referent, which is still entirely contained in some Rust allocation,
77- /// `A`
78- /// - If its referent is not zero sized, `A` is guaranteed to live for at least
79- /// `'a`
76+ /// First, by invariant on `SizeEq`, `src`'s address is unchanged, so it still
77+ /// satisfies its alignment. Since `dst`'s alignment is `Unaligned`, it
78+ /// trivially satisfies its alignment.
8079///
81- /// Since `Dst: SizeEq<Src>`, and since `dst` has the same address and metadata
82- /// as `src`, `dst` addresses the same byte range as `src`. `dst` also has the
83- /// same lifetime as `src`. Therefore, all of the `PtrInner` invariants
84- /// mentioned above also hold for `dst`.
85- ///
86- /// Second, since `src`'s address is unchanged, it still satisfies its
87- /// alignment. Since `dst`'s alignment is `Unaligned`, it trivially satisfies
88- /// its alignment.
89- ///
90- /// Third, aliasing is either `Exclusive` or `Shared`:
80+ /// Second, aliasing is either `Exclusive` or `Shared`:
9181/// - If it is `Exclusive`, then both `src` and `dst` satisfy `Exclusive`
9282/// aliasing trivially: since `src` and `dst` have the same lifetime, `src` is
9383/// inaccessible so long as `dst` is alive, and no other live `Ptr`s or
@@ -98,15 +88,15 @@ use crate::{
9888/// - It is explicitly sound for safe code to operate on a `&Src` and a `&Dst`
9989/// pointing to the same byte range at the same time.
10090///
101- /// Fourth , `src`'s validity is satisfied. By invariant, `src`'s referent began
91+ /// Third , `src`'s validity is satisfied. By invariant, `src`'s referent began
10292/// as an `SV`-valid `Src`. It is guaranteed to remain so, as either of the
10393/// following hold:
10494/// - `dst` does not permit mutation of its referent.
105- /// - The set of `DV`-valid `Dst`s is a superset of the set of `SV`-valid
106- /// `Src`s . Thus, any value written via `dst` is guaranteed to be `SV`-valid
107- /// for `Src `.
95+ /// - The set of `DV`-valid referents of `dst` is a subset of the set of
96+ /// `SV`-valid referents of `src` . Thus, any value written via `dst` is
97+ /// guaranteed to be an `SV`-valid referent of `src `.
10898///
109- /// Fifth , `dst`'s validity is satisfied. It is a given of this proof that the
99+ /// Fourth , `dst`'s validity is satisfied. It is a given of this proof that the
110100/// referent is `DV`-valid for `Dst`. It is guaranteed to remain so, as either
111101/// of the following hold:
112102/// - So long as `dst` is active, no mutation of the referent is allowed except
@@ -134,9 +124,11 @@ pub enum BecauseMutationCompatible {}
134124// - `Dst: TransmuteFrom<Src, SV, DV>`. Since `Dst: SizeEq<Src>`, this bound
135125// guarantees that the set of `DV`-valid `Dst`s is a supserset of the set of
136126// `SV`-valid `Src`s.
137- // - Reverse transmutation: `Src: TransmuteFrom<Dst, DV, SV>`. Since `Dst:
138- // SizeEq<Src>`, this guarantees that the set of `DV`-valid `Dst`s is a subset
139- // of the set of `SV`-valid `Src`s.
127+ // - Reverse transmutation: Since the underlying cast is performed using `<Dst
128+ // as SizeEq<Src>>::CastFrom::project`, `dst` addresses the same bytes as
129+ // `src`. By `Src: TransmuteFrom<Dst, DV, SV>`, the set of `DV`-valid `Dst`s
130+ // is a subset of the set of `SV`-valid `Src`s. Thus, the set of `DV`-valid
131+ // referents of `dst` is a subset of the set of `SV`-valid referents of `src`.
140132// - No safe code, given access to `src` and `dst`, can cause undefined
141133// behavior: By `Dst: MutationCompatible<Src, A, SV, DV, _>`, at least one of
142134// the following holds:
@@ -287,18 +279,20 @@ where
287279/// DV>` conveys no safety guarantee.
288280pub unsafe trait TransmuteFrom < Src : ?Sized , SV , DV > { }
289281
282+ /// Carries the ability to perform a size-preserving cast or conversion from a
283+ /// raw pointer to `Src` to a raw pointer to `Self`.
284+ ///
285+ /// The cast/conversion is carried by the associated [`CastFrom`] type, and
286+ /// may be a no-op cast (without updating pointer metadata) or a conversion
287+ /// which updates pointer metadata.
288+ ///
290289/// # Safety
291290///
292- /// `T` and `Self` must have the same vtable kind (`Sized`, slice DST, `dyn`,
293- /// etc) and have the same size. In particular:
294- /// - If `T: Sized` and `Self: Sized`, then their sizes must be equal
295- /// - If `T: ?Sized` and `Self: ?Sized`, then `Self::CastFrom` must be a
296- /// size-preserving cast. *Note that it is **not** guaranteed that an `as`
297- /// cast preserves referent size: it may be the case that `Self::CastFrom`
298- /// modifies the pointer's metadata in order to preserve referent size, which
299- /// an `as` cast does not do.*
300- pub unsafe trait SizeEq < T : ?Sized > {
301- type CastFrom : cast:: Cast < T , Self > ;
291+ /// The associated [`CastFrom`] must preserve referent size.
292+ ///
293+ /// [`CastFrom`]: SizeEq::CastFrom
294+ pub unsafe trait SizeEq < Src : ?Sized > {
295+ type CastFrom : cast:: Cast < Src , Self > ;
302296}
303297
304298// SAFETY: `T` trivially has the same size and vtable kind as `T`, and since
0 commit comments