1 | #![warn (rust_2018_idioms, single_use_lifetimes)] |
2 | // unaligned_references did not exist in older compilers and safe_packed_borrows was removed in the latest compilers. |
3 | // https://github.com/rust-lang/rust/pull/82525 |
4 | #![allow (unknown_lints, renamed_and_removed_lints)] |
5 | #![forbid (unaligned_references, safe_packed_borrows)] |
6 | |
7 | use std::cell::Cell; |
8 | |
9 | // Ensure that the compiler doesn't copy the fields |
10 | // of #[repr(packed)] types during drop, if the field has alignment 1 |
11 | // (that is, any reference to the field is guaranteed to have proper alignment) |
12 | // We are currently unable to statically prevent the usage of #[pin_project] |
13 | // on #[repr(packed)] types composed entirely of fields of alignment 1. |
14 | // This shouldn't lead to undefined behavior, as long as the compiler doesn't |
15 | // try to move the field anyway during drop. |
16 | // |
17 | // This tests validates that the compiler is doing what we expect. |
18 | #[test] |
19 | fn weird_repr_packed() { |
20 | // We keep track of the field address during |
21 | // drop using a thread local, to avoid changing |
22 | // the layout of our #[repr(packed)] type. |
23 | thread_local! { |
24 | static FIELD_ADDR: Cell<usize> = Cell::new(0); |
25 | } |
26 | |
27 | #[repr (packed)] |
28 | struct Struct { |
29 | field: u8, |
30 | } |
31 | |
32 | impl Drop for Struct { |
33 | fn drop(&mut self) { |
34 | FIELD_ADDR.with(|f| { |
35 | f.set(&self.field as *const u8 as usize); |
36 | }); |
37 | } |
38 | } |
39 | |
40 | #[allow (clippy::let_and_return)] |
41 | let field_addr = { |
42 | // We let this field drop by going out of scope, |
43 | // rather than explicitly calling drop(foo). |
44 | // Calling drop(foo) causes 'foo' to be moved |
45 | // into the 'drop' function, resulting in a different |
46 | // address. |
47 | let x = Struct { field: 27 }; |
48 | let field_addr = &x.field as *const u8 as usize; |
49 | field_addr |
50 | }; |
51 | assert_eq!(field_addr, FIELD_ADDR.with(Cell::get)); |
52 | } |
53 | |