diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index f458b3e6b68aa..6813c3bfe5859 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1810,22 +1810,22 @@ pub const unsafe fn read(src: *const T) -> T { pub const unsafe fn read_unaligned(src: *const T) -> T { // Always true thanks to the repr, but to demonstrate const { - assert!(mem::offset_of!(Packed::, 0) == 0); - assert!(size_of::() == size_of::>()); + assert!(mem::offset_of!(Unaligned::, 0) == 0); + assert!(size_of::() == size_of::>()); } - let src = src.cast::>(); + let src = src.cast::>(); // SAFETY: the caller must guarantee that `src` is valid for reads. - // Reading it as `Packed` instead of `T` reads those same bytes because + // Reading it as `Unaligned` instead of `T` reads those same bytes because // it's the same size (thus zero offset), but with alignment 1 instead. // // Similarly, because it's the same bytes it's sound to transmute from the - // `Packed` to `T`. Transmute is a value-based (not a place-based) + // `Unaligned` to `T`. Transmute is a value-based (not a place-based) // operation that doesn't care about alignment. unsafe { - let packed = read(src); + let unaligned = read(src); // Can't just destructure because that's not allowed in const fn - mem::transmute_neo(packed) + mem::transmute_neo(unaligned) } } @@ -2020,14 +2020,14 @@ pub const unsafe fn write(dst: *mut T, src: T) { pub const unsafe fn write_unaligned(dst: *mut T, src: T) { // Always true thanks to the repr, but to demonstrate const { - assert!(mem::offset_of!(Packed::, 0) == 0); - assert!(size_of::() == size_of::>()); + assert!(mem::offset_of!(Unaligned::, 0) == 0); + assert!(size_of::() == size_of::>()); } - let dst = dst.cast::>(); - let src = Packed(src); + let dst = dst.cast::>(); + let src = Unaligned(src); // SAFETY: the caller must guarantee that `dst` is valid for writes. - // Writing it as `Packed` instead of `T` writes those same bytes because + // Writing it as `Unaligned` instead of `T` writes those same bytes because // it's the same size (thus zero offset), but with alignment 1 instead. unsafe { write(dst, src) } } @@ -2828,5 +2828,7 @@ pub macro addr_of_mut($place:expr) { &raw mut $place } -#[repr(C, packed)] -struct Packed(T); +/// Used in [`read_unaligned`] and [`write_unaligned`] to load and store `T` +/// with alignment 1 rather than its usual `align_of::()` alignment. +#[repr(Rust, packed)] +struct Unaligned(T); diff --git a/tests/mir-opt/pre-codegen/unaligned.rs b/tests/mir-opt/pre-codegen/unaligned.rs index 4aeb10c261e21..ef59890b27ce6 100644 --- a/tests/mir-opt/pre-codegen/unaligned.rs +++ b/tests/mir-opt/pre-codegen/unaligned.rs @@ -24,11 +24,11 @@ pub unsafe fn unaligned_copy_generic(src: *const T, dst: *mut T) { // CHECK: debug src => _1; // CHECK: debug dst => _2; // CHECK: debug val => [[VAL:_.+]]; - // CHECK: [[SRC_P:_.+]] = copy _1 as *const {{.+}}::Packed (PtrToPtr); + // CHECK: [[SRC_P:_.+]] = copy _1 as *const {{.+}}::Unaligned (PtrToPtr); // CHECK: [[PACKED1:_.+]] = copy (*[[SRC_P]]); // CHECK: [[VAL]] = copy [[PACKED1]] as T (Transmute); - // CHECK: [[DST_P:_.+]] = copy _2 as *mut {{.+}}::Packed (PtrToPtr); - // CHECK: [[PACKED2:_.+]] = {{.+}}::Packed::(copy [[VAL]]); + // CHECK: [[DST_P:_.+]] = copy _2 as *mut {{.+}}::Unaligned (PtrToPtr); + // CHECK: [[PACKED2:_.+]] = {{.+}}::Unaligned::(copy [[VAL]]); // CHECK: (*[[DST_P]]) = copy [[PACKED2]]; // CHECK-NOT: copy_nonoverlapping // CHECK-NOT: drop diff --git a/tests/mir-opt/pre-codegen/unaligned.unaligned_copy_generic.runtime-optimized.after.mir b/tests/mir-opt/pre-codegen/unaligned.unaligned_copy_generic.runtime-optimized.after.mir index 4d0cfa6a4dfa3..ffb1fe334b201 100644 --- a/tests/mir-opt/pre-codegen/unaligned.unaligned_copy_generic.runtime-optimized.after.mir +++ b/tests/mir-opt/pre-codegen/unaligned.unaligned_copy_generic.runtime-optimized.after.mir @@ -8,46 +8,46 @@ fn unaligned_copy_generic(_1: *const T, _2: *mut T) -> () { scope 1 { debug val => _5; scope 8 (inlined #[track_caller] write_unaligned::) { - let _6: *mut std::ptr::Packed; + let _6: *mut std::ptr::Unaligned; scope 9 { - let _7: std::ptr::Packed; + let _7: std::ptr::Unaligned; scope 10 { - scope 12 (inlined #[track_caller] std::ptr::write::>) { + scope 12 (inlined #[track_caller] std::ptr::write::>) { } } } - scope 11 (inlined std::ptr::mut_ptr::::cast::>) { + scope 11 (inlined std::ptr::mut_ptr::::cast::>) { } } } scope 2 (inlined #[track_caller] read_unaligned::) { - let _3: *const std::ptr::Packed; + let _3: *const std::ptr::Unaligned; scope 3 { - let _4: std::ptr::Packed; + let _4: std::ptr::Unaligned; scope 4 { - scope 7 (inlined transmute_neo::, T>) { + scope 7 (inlined transmute_neo::, T>) { } } - scope 6 (inlined #[track_caller] std::ptr::read::>) { + scope 6 (inlined #[track_caller] std::ptr::read::>) { } } - scope 5 (inlined std::ptr::const_ptr::::cast::>) { + scope 5 (inlined std::ptr::const_ptr::::cast::>) { } } bb0: { StorageLive(_5); StorageLive(_3); - _3 = copy _1 as *const std::ptr::Packed (PtrToPtr); + _3 = copy _1 as *const std::ptr::Unaligned (PtrToPtr); StorageLive(_4); _4 = copy (*_3); _5 = copy _4 as T (Transmute); StorageDead(_4); StorageDead(_3); StorageLive(_6); - _6 = copy _2 as *mut std::ptr::Packed (PtrToPtr); + _6 = copy _2 as *mut std::ptr::Unaligned (PtrToPtr); StorageLive(_7); - _7 = std::ptr::Packed::(copy _5); + _7 = std::ptr::Unaligned::(copy _5); (*_6) = copy _7; StorageDead(_7); StorageDead(_6);