diff options
| -rw-r--r-- | src/test/run-pass/mir_adt_construction.rs | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/test/run-pass/mir_adt_construction.rs b/src/test/run-pass/mir_adt_construction.rs index 6b47721ab4b..c54cbe7bd6f 100644 --- a/src/test/run-pass/mir_adt_construction.rs +++ b/src/test/run-pass/mir_adt_construction.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::fmt; + #[repr(C)] enum CEnum { Hello = 30, @@ -24,7 +26,6 @@ fn test1(c: CEnum) -> i32 { } #[repr(packed)] -#[derive(PartialEq, Debug)] struct Pakd { a: u64, b: u32, @@ -33,6 +34,36 @@ struct Pakd { e: () } +// It is unsafe to use #[derive(Debug)] on a packed struct because the code generated by the derive +// macro takes references to the fields instead of accessing them directly. +impl fmt::Debug for Pakd { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // It's important that we load the fields into locals by-value here. This will do safe + // unaligned loads into the locals, then pass references to the properly-aligned locals to + // the formatting code. + let Pakd { a, b, c, d, e } = *self; + f.debug_struct("Pakd") + .field("a", &a) + .field("b", &b) + .field("c", &c) + .field("d", &d) + .field("e", &e) + .finish() + } +} + +// It is unsafe to use #[derive(PartialEq)] on a packed struct because the code generated by the +// derive macro takes references to the fields instead of accessing them directly. +impl PartialEq for Pakd { + fn eq(&self, other: &Pakd) -> bool { + self.a == other.a && + self.b == other.b && + self.c == other.c && + self.d == other.d && + self.e == other.e + } +} + impl Drop for Pakd { fn drop(&mut self) {} } |
