-
Notifications
You must be signed in to change notification settings - Fork 121
Teach transmute_{ref,mut}! to handle slice DSTs #2428
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
Conversation
829b199
to
a7c40db
Compare
4d09d7c
to
f2ec335
Compare
98bbab7
to
5196fac
Compare
398966d
to
976b234
Compare
bd3b50a
to
e972a2c
Compare
e2b7f7d
to
459de15
Compare
459de15
to
424ddb4
Compare
3931fcf
to
db9d6c0
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2428 +/- ##
==========================================
- Coverage 89.25% 88.85% -0.40%
==========================================
Files 19 20 +1
Lines 5126 5312 +186
==========================================
+ Hits 4575 4720 +145
- Misses 551 592 +41 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
src/pointer/transmute.rs
Outdated
t | ||
} | ||
} | ||
|
||
// TODO: Update all `TransmuteFrom` safety proofs. |
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
db9d6c0
to
d170d54
Compare
Dismissed because we forgot this important TODO: #2428 (comment)
d170d54
to
5d7c23b
Compare
85b4437
to
522d450
Compare
fbb37b8
to
bb9b06d
Compare
bb9b06d
to
38c910a
Compare
38c910a
to
454f974
Compare
// so permits interior mutation exactly when `T` does. | ||
unsafe_impl!(T: ?Sized + Immutable => Immutable for $dst<T>); | ||
|
||
$blk |
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.
Wonder if the outer unsafe
required to currently call this macro leaks into cover $blk
.
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.
Tried offline; turned out to be very difficult, so we're going to punt for now.
if 1 == 0 { | ||
let ptr = <$t as KnownLayout>::raw_dangling(); | ||
#[allow(unused_unsafe)] | ||
// SAFETY: This call is never executed. | ||
let ptr = unsafe { crate::pointer::PtrInner::new(ptr) }; | ||
#[allow(unused_unsafe)] | ||
// SAFETY: This call is never executed. | ||
let ptr = unsafe { cast!(ptr) }; | ||
let _ = <$dst<$u> as SizeEq<$src<$t>>>::cast_from_raw(ptr); | ||
} |
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.
We should drop a comment as to why this block exists.
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.
Is this okay? Can we rely on this PME occuring despite this code being dead?
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.
Comment: Done.
Can we rely on the PME: Maybe not, but the follow-up PR will ensure that it's sound since SizeEq
will no longer convey a safety post-condition that can be consumed by unsafe code - the only way to use it will be via SizeEq::cast_from_raw
, which will guarantee that the PME is triggered.
We generalize our existing support in `util::macro_util`, now relying on PMEs to detect when transmutes cannot be supported. In order to continue to support sized reference transmutation in a `const` context, we use the autoref specialization trick to fall back to our old (`const`-safe) implementation when both the source and destination type are `Sized`. The main challenge in generalizing this support is making a trait implementation available conditional on a PME. We do this using the `unsafe_with_size_eq!` helper macro, which introduces `#[repr(transparent)]` wrapper types, `Src` and `Dst`. Internal to this macro, we implement `SizeEq<Src<T>> for Dst<U>`, with the implementation of `SizeEq::cast_from_raw` containing the PME logic for size equality. The macro's caller must promise to only use the `Src` and `Dst` types to wrap the `T` and `U` types for which this PME logic has been applied (or else the `SizeEq` impl could "leak" to types for which it is unsound). In addition, we generalize our prior support for transmuting between unsized types. In particular, we previously used the `SizeEq` trait to denote that two types have equal sizes in the face of a cast operation (in particular, that `*const T as *const U` preserves referent size). In this commit, we add support for metadata fix-up, which means that we support casts for which `*const T as *const U` does *not* preserve referent size. Instead, we compute an affine function at compile time and apply it at runtime - computing the destination type's metadata as a function of the source metadata, `dst_meta = A + src_meta * B`. `A` and `B` are computed at compile time. We generalize `SizeEq` to permit its `cast_from_raw` method to perform a runtime metadata fix-up operation. Makes progress on #1817 Co-authored-by: Jack Wrenn <[email protected]> gherrit-pr-id: Ib4bc62202e0b3b09d155333b525087f7aa8f02c2
454f974
to
f5fcda2
Compare
We generalize our existing support in
util::macro_util
, now relying onPMEs to detect when transmutes cannot be supported. In order to continue
to support sized reference transmutation in a
const
context, we usethe autoref specialization trick to fall back to our old (
const
-safe)implementation when both the source and destination type are
Sized
.The main challenge in generalizing this support is making a trait
implementation available conditional on a PME. We do this using the
unsafe_with_size_eq!
helper macro, which introduces#[repr(transparent)]
wrapper types,Src
andDst
. Internal to thismacro, we implement
SizeEq<Src<T>> for Dst<U>
, with the implementationof
SizeEq::cast_from_raw
containing the PME logic for size equality.The macro's caller must promise to only use the
Src
andDst
typesto wrap the
T
andU
types for which this PME logic has been applied(or else the
SizeEq
impl could "leak" to types for which it isunsound).
In addition, we generalize our prior support for transmuting between
unsized types. In particular, we previously used the
SizeEq
trait todenote that two types have equal sizes in the face of a cast operation
(in particular, that
*const T as *const U
preserves referent size). Inthis commit, we add support for metadata fix-up, which means that we
support casts for which
*const T as *const U
does not preservereferent size. Instead, we compute an affine function at compile time
and apply it at runtime - computing the destination type's metadata as a
function of the source metadata,
dst_meta = A + src_meta * B
.A
andB
are computed at compile time.We generalize
SizeEq
to permit itscast_from_raw
method to perform aruntime metadata fix-up operation.
Makes progress on #1817
Co-authored-by: Jack Wrenn [email protected]
This PR is on branch transmute-ref-dst.
TransmuteFrom
safety proofs #2469