summaryrefslogtreecommitdiffstats
path: root/src/test/ui/mir/mir_adt_construction.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/mir/mir_adt_construction.rs')
-rw-r--r--src/test/ui/mir/mir_adt_construction.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/test/ui/mir/mir_adt_construction.rs b/src/test/ui/mir/mir_adt_construction.rs
new file mode 100644
index 000000000..9fb5896de
--- /dev/null
+++ b/src/test/ui/mir/mir_adt_construction.rs
@@ -0,0 +1,92 @@
+// run-pass
+use std::fmt;
+
+#[repr(C)]
+enum CEnum {
+ Hello = 30,
+ World = 60
+}
+
+fn test1(c: CEnum) -> i32 {
+ let c2 = CEnum::Hello;
+ match (c, c2) {
+ (CEnum::Hello, CEnum::Hello) => 42,
+ (CEnum::World, CEnum::Hello) => 0,
+ _ => 1
+ }
+}
+
+#[repr(packed)]
+struct Pakd {
+ a: u64,
+ b: u32,
+ c: u16,
+ d: u8,
+ 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) {}
+}
+
+fn test2() -> Pakd {
+ Pakd { a: 42, b: 42, c: 42, d: 42, e: () }
+}
+
+#[derive(PartialEq, Debug)]
+struct TupleLike(u64, u32);
+
+fn test3() -> TupleLike {
+ TupleLike(42, 42)
+}
+
+fn test4(x: fn(u64, u32) -> TupleLike) -> (TupleLike, TupleLike) {
+ let y = TupleLike;
+ (x(42, 84), y(42, 84))
+}
+
+fn test5(x: fn(u32) -> Option<u32>) -> (Option<u32>, Option<u32>) {
+ let y = Some;
+ (x(42), y(42))
+}
+
+fn main() {
+ assert_eq!(test1(CEnum::Hello), 42);
+ assert_eq!(test1(CEnum::World), 0);
+ assert_eq!(test2(), Pakd { a: 42, b: 42, c: 42, d: 42, e: () });
+ assert_eq!(test3(), TupleLike(42, 42));
+ let t4 = test4(TupleLike);
+ assert_eq!(t4.0, t4.1);
+ let t5 = test5(Some);
+ assert_eq!(t5.0, t5.1);
+}