about summary refs log tree commit diff
path: root/compiler/rustc_error_codes/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2022-09-30 14:54:30 +0200
committerRalf Jung <post@ralfj.de>2023-01-31 20:28:11 +0100
commitdfc4a7b2d02528f246e455f587605cce224bb99c (patch)
tree36b96c1f46b9ce4d490eefaf4f77ac273595101c /compiler/rustc_error_codes/src
parentf361413cbf44ce2f144df59fc440cd484af4a56e (diff)
downloadrust-dfc4a7b2d02528f246e455f587605cce224bb99c.tar.gz
rust-dfc4a7b2d02528f246e455f587605cce224bb99c.zip
make unaligned_reference a hard error
Diffstat (limited to 'compiler/rustc_error_codes/src')
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs3
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0793.md64
2 files changed, 66 insertions, 1 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 4ae372bb904..072b0f2fcce 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -5,7 +5,7 @@
 // /!\ IMPORTANT /!\
 //
 // Error messages' format must follow the RFC 1567 available here:
-// https://github.com/rust-lang/rfcs/pull/1567
+// https://rust-lang.github.io/rfcs/1567-long-error-codes-explanation-normalization.html
 
 register_diagnostics! {
 E0001: include_str!("./error_codes/E0001.md"),
@@ -510,6 +510,7 @@ E0789: include_str!("./error_codes/E0789.md"),
 E0790: include_str!("./error_codes/E0790.md"),
 E0791: include_str!("./error_codes/E0791.md"),
 E0792: include_str!("./error_codes/E0792.md"),
+E0793: include_str!("./error_codes/E0793.md"),
 ;
 //  E0006, // merged with E0005
 //  E0008, // cannot bind by-move into a pattern guard
diff --git a/compiler/rustc_error_codes/src/error_codes/E0793.md b/compiler/rustc_error_codes/src/error_codes/E0793.md
new file mode 100644
index 00000000000..b2e51e24e14
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0793.md
@@ -0,0 +1,64 @@
+An unaligned references to a field of a [packed] struct got created.
+
+Erroneous code example:
+
+```compile_fail,E0793
+#[repr(packed)]
+pub struct Foo {
+    field1: u64,
+    field2: u8,
+}
+
+unsafe {
+    let foo = Foo { field1: 0, field2: 0 };
+    // Accessing the field directly is fine.
+    let val = foo.field1;
+    // A reference to a packed field causes a error.
+    let val = &foo.field1; // ERROR
+    // An implicit `&` is added in format strings, causing the same error.
+    println!("{}", foo.field1); // ERROR
+}
+```
+
+Creating a reference to an insufficiently aligned packed field is
+[undefined behavior] and therefore disallowed. Using an `unsafe` block does not
+change anything about this. Instead, the code should do a copy of the data in
+the packed field or use raw pointers and unaligned accesses.
+
+```
+#[repr(packed)]
+pub struct Foo {
+    field1: u64,
+    field2: u8,
+}
+
+unsafe {
+    let foo = Foo { field1: 0, field2: 0 };
+
+    // Instead of a reference, we can create a raw pointer...
+    let ptr = std::ptr::addr_of!(foo.field1);
+    // ... and then (crucially!) access it in an explicitly unaligned way.
+    let val = unsafe { ptr.read_unaligned() };
+    // This would *NOT* be correct:
+    // let val = unsafe { *ptr }; // Undefined Behavior due to unaligned load!
+
+    // For formatting, we can create a copy to avoid the direct reference.
+    let copy = foo.field1;
+    println!("{}", copy);
+    // Creating a copy can be written in a single line with curly braces.
+    // (This is equivalent to the two lines above.)
+    println!("{}", { foo.field1 });
+}
+```
+
+### Additional information
+
+Note that this error is specifically about *references* to packed fields.
+Direct by-value access of those fields is fine, since then the compiler has
+enough information to generate the correct kind of access.
+
+See [issue #82523] for more information.
+
+[packed]: https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers
+[undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+[issue #82523]: https://github.com/rust-lang/rust/issues/82523