diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 62805d1e8b5c9..d981f52436e9b 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -345,11 +345,16 @@ impl<'tcx> SizeSkeleton<'tcx> { ty::Array(inner, len) if len.ty() == tcx.types.usize && tcx.features().transmute_generic_consts => { + let len_eval = len.try_eval_target_usize(tcx, param_env); + if len_eval == Some(0) { + return Ok(SizeSkeleton::Known(Size::from_bytes(0))); + } + match SizeSkeleton::compute(inner, tcx, param_env)? { // This may succeed because the multiplication of two types may overflow // but a single size of a nested array will not. SizeSkeleton::Known(s) => { - if let Some(c) = len.try_eval_target_usize(tcx, param_env) { + if let Some(c) = len_eval { let size = s .bytes() .checked_mul(c) diff --git a/tests/ui/transmute/transmute-zst-generics.rs b/tests/ui/transmute/transmute-zst-generics.rs new file mode 100644 index 0000000000000..469ad632d4260 --- /dev/null +++ b/tests/ui/transmute/transmute-zst-generics.rs @@ -0,0 +1,14 @@ +// run-pass +// Transmuting to/from ZSTs that contain generics. + +#![feature(transmute_generic_consts)] + +unsafe fn cast_zst(from: ()) -> [T; 0] { + ::std::mem::transmute::<(), [T; 0]>(from) +} + +pub fn main() { + unsafe { + let _: [u32; 0] = cast_zst(()); + }; +}