Skip to content

Commit b955aa7

Browse files
authored
Rollup merge of rust-lang#144944 - He1pa:E0793, r=compiler-errors
E0793: Clarify that it applies to unions as well pick up inactive PR: rust-lang#131472 Also: Adjust the language slightly to be more consistent with other similar messages (was created instead of got created). Add a short section on union. Add an example line showing referencing a field in a packed struct is safe if the field's type isn't more strictly aligned than the pack. r? compiler-errors
2 parents 44eb7a1 + 57901fe commit b955aa7

File tree

1 file changed

+33
-1
lines changed
  • compiler/rustc_error_codes/src/error_codes

1 file changed

+33
-1
lines changed

compiler/rustc_error_codes/src/error_codes/E0793.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
An unaligned reference to a field of a [packed] struct got created.
1+
An unaligned reference to a field of a [packed] `struct` or `union` was created.
2+
3+
The `#[repr(packed)]` attribute removes padding between fields, which can
4+
cause fields to be stored at unaligned memory addresses. Creating references
5+
to such fields violates Rust's memory safety guarantees and can lead to
6+
undefined behavior in optimized code.
27

38
Erroneous code example:
49

@@ -45,9 +50,36 @@ unsafe {
4550
// For formatting, we can create a copy to avoid the direct reference.
4651
let copy = foo.field1;
4752
println!("{}", copy);
53+
4854
// Creating a copy can be written in a single line with curly braces.
4955
// (This is equivalent to the two lines above.)
5056
println!("{}", { foo.field1 });
57+
58+
// A reference to a field that will always be sufficiently aligned is safe:
59+
println!("{}", foo.field2);
60+
}
61+
```
62+
63+
### Unions
64+
65+
Although creating a reference to a `union` field is `unsafe`, this error
66+
will still be triggered if the referenced field is not sufficiently
67+
aligned. Use `addr_of!` and raw pointers in the same way as for struct fields.
68+
69+
```compile_fail,E0793
70+
#[repr(packed)]
71+
pub union Foo {
72+
field1: u64,
73+
field2: u8,
74+
}
75+
76+
unsafe {
77+
let foo = Foo { field1: 0 };
78+
// Accessing the field directly is fine.
79+
let val = foo.field1;
80+
81+
// A reference to a packed union field causes an error.
82+
let val = &foo.field1; // ERROR
5183
}
5284
```
5385

0 commit comments

Comments
 (0)