about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs4
-rw-r--r--src/test/ui/transmute/transmute-padding-ice.rs29
-rw-r--r--src/test/ui/transmute/transmute-padding-ice.stderr24
3 files changed, 55 insertions, 2 deletions
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index 2bc6bc1fc23..30e20ba6f58 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -436,8 +436,8 @@ pub(crate) mod rustc {
 
             // finally: padding
             let padding_span = trace_span!("adding trailing padding").entered();
-            let padding_needed = layout_summary.total_size - variant_layout.size();
-            if padding_needed > 0 {
+            if layout_summary.total_size > variant_layout.size() {
+                let padding_needed = layout_summary.total_size - variant_layout.size();
                 tree = tree.then(Self::padding(padding_needed));
             };
             drop(padding_span);
diff --git a/src/test/ui/transmute/transmute-padding-ice.rs b/src/test/ui/transmute/transmute-padding-ice.rs
new file mode 100644
index 00000000000..a1be7075a8a
--- /dev/null
+++ b/src/test/ui/transmute/transmute-padding-ice.rs
@@ -0,0 +1,29 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<
+            Src,
+            Context,
+            { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+        >,
+    {
+    }
+}
+
+fn test() {
+    #[repr(C, align(2))]
+    struct A(u8, u8);
+
+    #[repr(C)]
+    struct B(u8, u8);
+
+    assert::is_maybe_transmutable::<B, A>();
+    //~^ ERROR cannot be safely transmuted
+}
diff --git a/src/test/ui/transmute/transmute-padding-ice.stderr b/src/test/ui/transmute/transmute-padding-ice.stderr
new file mode 100644
index 00000000000..c9233890f7a
--- /dev/null
+++ b/src/test/ui/transmute/transmute-padding-ice.stderr
@@ -0,0 +1,24 @@
+error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
+  --> $DIR/transmute-padding-ice.rs:27:40
+   |
+LL |     assert::is_maybe_transmutable::<B, A>();
+   |                                        ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`.
+   |
+   = help: the trait `BikeshedIntrinsicFrom<B, assert::Context, Assume { alignment: true, lifetimes: true, safety: true, validity: true }>` is not implemented for `A`
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/transmute-padding-ice.rs:11:14
+   |
+LL |       pub fn is_maybe_transmutable<Src, Dst>()
+   |              --------------------- required by a bound in this
+LL |       where
+LL |           Dst: BikeshedIntrinsicFrom<
+   |  ______________^
+LL | |             Src,
+LL | |             Context,
+LL | |             { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
+LL | |         >,
+   | |_________^ required by this bound in `is_maybe_transmutable`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.