-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Teach transmute_{ref,mut}! to handle slice DSTs #2428
base: I691b42ce8c0c3c6e5990e7684fc66f8f5dd73d85
Are you sure you want to change the base?
Teach transmute_{ref,mut}! to handle slice DSTs #2428
Conversation
829b199
to
a7c40db
Compare
4d09d7c
to
f2ec335
Compare
98bbab7
to
5196fac
Compare
/// constructed using the address of `src` and using `dst_meta` as its | ||
/// pointer metadata, then `dst` will address the same bytes as `src`. | ||
/// | ||
/// TODO: Mention that post-padding may not be preserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
// | ||
// (15) `dst_len = src_len` | ||
// | ||
// [1] TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
// | ||
// [1] TODO | ||
// | ||
// TODO: Clarify that this algorithm is agnostic to post-padding, and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
#[allow(clippy::arithmetic_side_effects)] | ||
let elem_multiple = slf.elem_size / other.elem_size; | ||
|
||
// INVARIANTS: TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
$crate::util::macro_util::must_use(u) | ||
use $crate::util::macro_util::TransmuteRefDst; | ||
let t = $crate::util::macro_util::Wrap(e); | ||
// SAFETY: todo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
// SAFETY: TODO | ||
unsafe_impl_for_transparent_wrapper!(T: ?Sized => $dst<T>); | ||
|
||
// SAFETY: TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
// SAFETY: TODO | ||
unsafe impl<T: ?Sized> InvariantsEq<$src<T>> for T {} | ||
|
||
// SAFETY: TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
// SAFETY: TODO | ||
unsafe impl<T: ?Sized> InvariantsEq<$dst<T>> for T {} | ||
|
||
// SAFETY: TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
impl_for_transmute_from!(U: ?Sized + FromZeros => FromZeros for $dst<U>[<U>]); | ||
impl_for_transmute_from!(U: ?Sized + IntoBytes => IntoBytes for $dst<U>[<U>]); | ||
|
||
// SAFETY: TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
// SAFETY: TODO | ||
unsafe_impl!(T: ?Sized + Immutable => Immutable for $src<T>); | ||
|
||
// SAFETY: TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO
398966d
to
976b234
Compare
8634aa4
to
bd3b50a
Compare
TODO: - Convince ourselves that it's acceptable to drop the `TransmuteFrom: SizeCompatible` super-trait bound. - Write Kani tests for layout computations - Print useful error message when `try_compute_cast_params` fails during static assertion - Test when post padding doesn't match between types - Do we need to prevent the padded size from increasing? While it's not a problem on today's Rust, it would become a problem if unsized locals are ever introduced, as you could then do `*dst = ...`, which would have the effect of writing padding past the end of `*src` Makes progress on #1817 Co-authored-by: Jack Wrenn <[email protected]> gherrit-pr-id: Ib4bc62202e0b3b09d155333b525087f7aa8f02c2
bd3b50a
to
e972a2c
Compare
/// For all [valid sizes] of `Src`, `ssize`, the following must hold: | ||
/// | ||
/// Let `dsize` be the smallest valid size of `Dst` such that `dsize >= | ||
/// ssize`.\* For all `DV`-valid values of `Dst` with size `dsize`, `dst`, and | ||
/// for all `SV`-valid values of `Src` with size `ssize`, `src`, let `dst'` be | ||
/// constructed by concatenating `src` with the trailing `dsize - ssize` bytes | ||
/// of `dst`. It must be the case that `dst'` is a `DV`-valid `Dst`. | ||
/// | ||
/// Now, instead let `dsize` be the largest valid size of `Dst` such that `dsize | ||
/// <= ssize`.\* For all `SV`-valid values of `Src` with size `ssize`, `src`, it | ||
/// must be the case that the leading `dsize` bytes of `src` constitute a | ||
/// `DV`-valid `Dst`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The motivation behind this invariant is case analysis:
- When going from
&Src
to&Dst
, we require thatssize >= dsize
, or else we'd produce a&Dst
that addresses bytes past the end of the original referent. So long as we always implement such transmutes by choosing the largestdsize
such thatdsize <= ssize
, then the second condition ensures that this is sound. - If we have already gone from
&mut Dst
to&mut Src
(or&
with interior mutation), then we need it to be the case that writing asrc
to this reference will not invalidate the originalDst
. Again, so long as we always implement reference transmutes by choosing the largest possible valid size for the produced reference, then the first condition ensures that it is sound for the resulting&mut Src
to be modified, overwriting the prefix ofDst
.
My intention is that this should handle by-reference transmutations for all four combinations of sized or unsized Src
to sized or unsized Dst
:
- Unsized to unsized is the fully general case described by this prose.
- Sized to unsized means that there's exactly one value of
ssize
, but the subsequent condition still needs to hold (regarding the largest and smallest values ofdsize
on either size ofssize
). - Unsized to sized means that there's exactly one value of
dsize
to consider in the analysis- For all values of
ssize
such thatdsize <= ssize
, we consider truncating transmutes - For all values of
ssize
such thatdsize >= ssize
, we consider tearing transmutes
- For all values of
- Sized to sized is trivial, since there are no "foralls" or "there exists" involved. There are again two sub-cases:
- If
dsize <= ssize
, we must consider truncating transmutes - If
dsize >= ssize
, we must consider tearing transmutes
- If
TODO:
TransmuteFrom: SizeCompatible
super-trait bound.try_compute_cast_params
fails duringstatic assertion
a problem on today's Rust, it would become a problem if unsized locals
are ever introduced, as you could then do
*dst = ...
, which wouldhave the effect of writing padding past the end of
*src
Makes progress on #1817
Co-authored-by: Jack Wrenn [email protected]
This PR is on branch cell-traits.