From 9eaa65a084f6cabafb74e4cea832f173e89bd56c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= <54238857+yjhn@users.noreply.github.com> Date: Wed, 14 Jun 2023 08:49:57 +0300 Subject: [PATCH 1/3] Remove note about soundness hole in type-layout.md Issue https://github.com/rust-lang/rust/issues/27060 has been resolved, so it is no longer possible to safely create unaligned pointers to packed struct fields. --- src/type-layout.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/type-layout.md b/src/type-layout.md index 191567a42..9ecb784cf 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -549,13 +549,7 @@ The `align` modifier can also be applied on an `enum`. When it is, the effect on the `enum`'s alignment is the same as if the `enum` was wrapped in a newtype `struct` with the same `align` modifier. -
- -***Warning:*** Dereferencing an unaligned pointer is [undefined behavior] and -it is possible to [safely create unaligned pointers to `packed` fields][27060]. -Like all ways to create undefined behavior in safe Rust, this is a bug. - -
+Dereferencing an unaligned pointer is [undefined behavior]. ### The `transparent` Representation From cbbff21d042fc1e24456fc257b023895a59fe33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= <54238857+yjhn@users.noreply.github.com> Date: Thu, 15 Jun 2023 16:21:08 +0300 Subject: [PATCH 2/3] Apply review suggestion --- src/type-layout.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/type-layout.md b/src/type-layout.md index 9ecb784cf..de16ac485 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -549,7 +549,28 @@ The `align` modifier can also be applied on an `enum`. When it is, the effect on the `enum`'s alignment is the same as if the `enum` was wrapped in a newtype `struct` with the same `align` modifier. -Dereferencing an unaligned pointer is [undefined behavior]. +> Note: References to unaligned fields are not allowed because it is [undefined behavior]. +> When fields are unaligned due to an alignment modifier, consider the following options for using references and dereferences: +> +> ```rust +> #[repr(packed)] +> struct Packed { +> f1: u8, +> f2: u16, +> } +> let mut e = Packed { f1: 1, f2: 2 }; +> // Instead of creating a reference to a field, copy the value to a local variable. +> let x = e.f2; +> // Or in situations like `println!` which creates a reference, use braces +> // to change it to a copy of the value. +> println!("{}", {e.f2}); +> // Or if you need a pointer, use the unaligned methods for reading and writing +> // instead of dereferencing the pointer directly. +> let ptr: *const u16 = std::ptr::addr_of!(e.f2); +> let value = unsafe { ptr.read_unaligned() }; +> let mut_ptr: *mut u16 = std::ptr::addr_of_mut!(e.f2); +> unsafe { mut_ptr.write_unaligned(3) } +> ``` ### The `transparent` Representation @@ -581,7 +602,6 @@ used with any other representation. [enumerations]: items/enumerations.md [zero-variant enums]: items/enumerations.md#zero-variant-enums [undefined behavior]: behavior-considered-undefined.md -[27060]: https://github.com/rust-lang/rust/issues/27060 [55149]: https://github.com/rust-lang/rust/issues/55149 [`PhantomData`]: special-types-and-traits.md#phantomdatat [Default]: #the-default-representation From 2dc423d6937754e07e42345156021d3ef8ff956b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= <54238857+yjhn@users.noreply.github.com> Date: Thu, 15 Jun 2023 16:24:19 +0300 Subject: [PATCH 3/3] remove space at the end of line --- src/type-layout.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/type-layout.md b/src/type-layout.md index de16ac485..4c87954f3 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -551,7 +551,7 @@ was wrapped in a newtype `struct` with the same `align` modifier. > Note: References to unaligned fields are not allowed because it is [undefined behavior]. > When fields are unaligned due to an alignment modifier, consider the following options for using references and dereferences: -> +> > ```rust > #[repr(packed)] > struct Packed {