From f832add613ee8b3849735e9f38e6e9ec060e88b4 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Fri, 9 Jun 2023 07:37:24 -0400 Subject: [PATCH 1/3] Make `std::mem::transmute_copy` accept `?Sized` inputs This enables conversions from dynamically-sized types like `[u8]`. --- library/core/src/mem/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 39c9a04eea92b..800eeddf207b1 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1052,14 +1052,14 @@ pub const fn copy(x: &T) -> T { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_transmute_copy", issue = "83165")] -pub const unsafe fn transmute_copy(src: &Src) -> Dst { +pub const unsafe fn transmute_copy(src: &Src) -> Dst { assert!( - size_of::() >= size_of::(), + size_of_val(src) >= size_of::(), "cannot transmute_copy if Dst is larger than Src" ); // If Dst has a higher alignment requirement, src might not be suitably aligned. - if align_of::() > align_of::() { + if align_of::() > align_of_val(src) { // SAFETY: `src` is a reference which is guaranteed to be valid for reads. // The caller must guarantee that the actual transmutation is safe. unsafe { ptr::read_unaligned(src as *const Src as *const Dst) } From c9575a6a67a5985370885fab44061c4de69c6f62 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Fri, 9 Jun 2023 07:51:05 -0400 Subject: [PATCH 2/3] Add `std::mem::transmute_copy` slice test --- library/core/tests/mem.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index 5c2e18745ea21..0b73a4d56d34e 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -121,6 +121,11 @@ fn test_transmute_copy_shrink() { assert_eq!(0_u8, unsafe { transmute_copy(&0_u64) }); } +#[test] +fn test_transmute_copy_slice() { + assert_eq!(1, unsafe { transmute_copy(&[1][..]) }); +} + #[test] fn test_transmute_copy_unaligned() { #[repr(C)] From 3f1825a2e26e0973d46504be19499b990c38e8e9 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Fri, 9 Jun 2023 09:53:07 -0400 Subject: [PATCH 3/3] Change `std::mem::transmute_copy` to use `debug_assert!` Code that uses this function is likely performance-sensitive, so we do not want to emit an assert for dynamically-sized types in release mode. --- library/core/src/mem/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 800eeddf207b1..87b10d17aab3f 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1053,7 +1053,7 @@ pub const fn copy(x: &T) -> T { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_transmute_copy", issue = "83165")] pub const unsafe fn transmute_copy(src: &Src) -> Dst { - assert!( + debug_assert!( size_of_val(src) >= size_of::(), "cannot transmute_copy if Dst is larger than Src" );