Error code E0793
An unaligned references to a field of a packed struct got created.
Erroneous code example:
#![allow(unused)] fn main() { #[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.
#![allow(unused)] fn main() { #[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.