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() + 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::(); + //~^ 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` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom` 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() + | --------------------- 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`.