about summary refs log tree commit diff
path: root/compiler/rustc_transmute/src/lib.rs
diff options
context:
space:
mode:
authorJack Wrenn <jack@wrenn.fyi>2024-03-13 00:11:36 +0000
committerJack Wrenn <jack@wrenn.fyi>2024-03-13 15:53:48 +0000
commit216df4a8e6358a515ba95fb1a92864d1b94c37f3 (patch)
tree8bfa6be348f0cca0fc53705def0763e3647544b9 /compiler/rustc_transmute/src/lib.rs
parenta165f1f65015b1bd4afd2ec50700aaacf2e0c485 (diff)
downloadrust-216df4a8e6358a515ba95fb1a92864d1b94c37f3.tar.gz
rust-216df4a8e6358a515ba95fb1a92864d1b94c37f3.zip
safe transmute: require that src referent is smaller than dst
The source referent absolutely must be smaller than the destination
referent of a ref-to-ref transmute; the excess bytes referenced
cannot arise from thin air, even if those bytes are uninitialized.
Diffstat (limited to 'compiler/rustc_transmute/src/lib.rs')
-rw-r--r--compiler/rustc_transmute/src/lib.rs11
1 files changed, 9 insertions, 2 deletions
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index fefce2640eb..8f3af491453 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -23,7 +23,7 @@ pub struct Assume {
 #[derive(Debug, Hash, Eq, PartialEq, Clone)]
 pub enum Answer<R> {
     Yes,
-    No(Reason),
+    No(Reason<R>),
     If(Condition<R>),
 }
 
@@ -42,7 +42,7 @@ pub enum Condition<R> {
 
 /// Answers "why wasn't the source type transmutable into the destination type?"
 #[derive(Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Clone)]
-pub enum Reason {
+pub enum Reason<T> {
     /// The layout of the source type is unspecified.
     SrcIsUnspecified,
     /// The layout of the destination type is unspecified.
@@ -53,6 +53,13 @@ pub enum Reason {
     DstMayHaveSafetyInvariants,
     /// `Dst` is larger than `Src`, and the excess bytes were not exclusively uninitialized.
     DstIsTooBig,
+    /// A referent of `Dst` is larger than a referent in `Src`.
+    DstRefIsTooBig {
+        /// The referent of the source type.
+        src: T,
+        /// The too-large referent of the destination type.
+        dst: T,
+    },
     /// Src should have a stricter alignment than Dst, but it does not.
     DstHasStricterAlignment { src_min_align: usize, dst_min_align: usize },
     /// Can't go from shared pointer to unique pointer