Skip to content

Commit 8529fd1

Browse files
committed
Permit shrinking transmutes in transmute machinery
Makes progress on #2701, #1940, #1852 gherrit-pr-id: Gd9d1c0de851091ffe6161889d21ca2167845a591
1 parent a4ef307 commit 8529fd1

File tree

1 file changed

+17
-23
lines changed

1 file changed

+17
-23
lines changed

src/pointer/transmute.rs

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ 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 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)
52+
/// - `<Dst as SizeEq<Src>>::CastFrom: CastExact`, and the set of `DV`-valid
53+
/// referents of `dst` is a subset of the set of `SV`-valid referents of
54+
/// `src`
5655
/// - No safe code, given access to `src` and `dst`, can cause undefined
5756
/// behavior: Any of the following hold:
5857
/// - `A` is `Exclusive`
@@ -92,9 +91,11 @@ use crate::{
9291
/// as an `SV`-valid `Src`. It is guaranteed to remain so, as either of the
9392
/// following hold:
9493
/// - `dst` does not permit mutation of its referent.
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`.
94+
/// - `<Dst as SizeEq<Src>>::CastFrom: CastExact`, and the set of `DV`-valid
95+
/// referents of `dst` is a subset of the set of `SV`-valid referents of
96+
/// `src`. By `CastExact`, `src` and `dst` address the same number of bytes.
97+
/// Thus, any value written via `dst` is guaranteed to be an `SV`-valid
98+
/// referent of `src`.
9899
///
99100
/// Fourth, `dst`'s validity is satisfied. It is a given of this proof that the
100101
/// referent is `DV`-valid for `Dst`. It is guaranteed to remain so, as either
@@ -112,15 +113,6 @@ pub unsafe trait TryTransmuteFromPtr<Src: ?Sized, A: Aliasing, SV: Validity, DV:
112113
#[allow(missing_copy_implementations, missing_debug_implementations)]
113114
pub enum BecauseMutationCompatible {}
114115

115-
// TODO: Update this comment to not rely on `SizeEq` implying size equality
116-
// (but instead rely on *runtime execution* of `SizeEq::CastFrom_inner`
117-
// guaranteeing size compatibility) and not to rely on size equality (as opposed
118-
// to size compatibility). Notably, the following lines assume size equality:
119-
//
120-
// - Reverse transmutation: `Src: TransmuteFrom<Dst, DV, SV>`. Since `Dst:
121-
// SizeEq<Src>`, this guarantees that the set of `DV`-valid `Dst`s is a
122-
// subset of the set of `SV`-valid `Src`s.
123-
124116
// SAFETY:
125117
// - Forwards transmutation: By `Dst: MutationCompatible<Src, A, SV, DV, _>`, we
126118
// know that at least one of the following holds:
@@ -134,10 +126,11 @@ pub enum BecauseMutationCompatible {}
134126
// guarantees that the set of `DV`-valid `Dst`s is a supserset of the set of
135127
// `SV`-valid `Src`s.
136128
// - Reverse transmutation: Since the underlying cast is performed using `<Dst
137-
// as SizeEq<Src>>::CastFrom::project`, `dst` addresses the same bytes as
138-
// `src`. By `Src: TransmuteFrom<Dst, DV, SV>`, the set of `DV`-valid `Dst`s
139-
// is a subset of the set of `SV`-valid `Src`s. Thus, the set of `DV`-valid
140-
// referents of `dst` is a subset of the set of `SV`-valid referents of `src`.
129+
// as SizeEq<Src>>::CastFrom::project`, and since `Dst::CastFrom: CastExact`,
130+
// `dst` addresses the same bytes as `src`. By `Src: TransmuteFrom<Dst, DV,
131+
// SV>`, the set of `DV`-valid `Dst`s is a subset of the set of `SV`-valid
132+
// `Src`s. Thus, the set of `DV`-valid referents of `dst` is a subset of the
133+
// set of `SV`-valid referents of `src`.
141134
// - No safe code, given access to `src` and `dst`, can cause undefined
142135
// behavior: By `Dst: MutationCompatible<Src, A, SV, DV, _>`, at least one of
143136
// the following holds:
@@ -153,6 +146,7 @@ where
153146
DV: Validity,
154147
Src: TransmuteFrom<Dst, DV, SV> + ?Sized,
155148
Dst: MutationCompatible<Src, A, SV, DV, R> + SizeEq<Src> + ?Sized,
149+
Dst::CastFrom: cast::CastExact<Src, Dst>,
156150
{
157151
}
158152

@@ -299,12 +293,12 @@ pub unsafe trait TransmuteFrom<Src: ?Sized, SV, DV> {}
299293
///
300294
/// `SizeEq` on its own conveys no safety guarantee. Any safety guarantees come
301295
/// from the safety invariants on the associated [`CastFrom`] type, specifically
302-
/// the [`CastExact`] bound.
296+
/// the [`Cast`] bound.
303297
///
304298
/// [`CastFrom`]: SizeEq::CastFrom
305-
/// [`CastExact`]: cast::CastExact
299+
/// [`Cast`]: cast::Cast
306300
pub trait SizeEq<Src: ?Sized> {
307-
type CastFrom: cast::CastExact<Src, Self>;
301+
type CastFrom: cast::Cast<Src, Self>;
308302
}
309303

310304
impl<T: ?Sized> SizeEq<T> for T {

0 commit comments

Comments
 (0)