#![feature(untagged_unions)] #![allow(dead_code, unused_variables)] fn main() { a(); b(); c(); d(); } fn a() { union U { f1: u32, f2: f32, } let mut u = U { f1: 1 }; unsafe { let b1 = &mut u.f1; *b1 = 5; } assert_eq!(unsafe { u.f1 }, 5); } fn b() { struct S { x: u32, y: u32, } union U { s: S, both: u64, } let mut u = U { s: S { x: 1, y: 2 } }; unsafe { let bx = &mut u.s.x; let by = &mut u.s.y; *bx = 5; *by = 10; } assert_eq!(unsafe { u.s.x }, 5); assert_eq!(unsafe { u.s.y }, 10); } fn c() { #[repr(u32)] enum Tag { I, F } #[repr(C)] union U { i: i32, f: f32, } #[repr(C)] struct Value { tag: Tag, u: U, } fn is_zero(v: Value) -> bool { unsafe { match v { Value { tag: Tag::I, u: U { i: 0 } } => true, Value { tag: Tag::F, u: U { f } } if f == 0.0 => true, _ => false, } } } assert!(is_zero(Value { tag: Tag::I, u: U { i: 0 }})); assert!(is_zero(Value { tag: Tag::F, u: U { f: 0.0 }})); assert!(!is_zero(Value { tag: Tag::I, u: U { i: 1 }})); assert!(!is_zero(Value { tag: Tag::F, u: U { f: 42.0 }})); } fn d() { union MyUnion { f1: u32, f2: f32, } let u = MyUnion { f1: 10 }; unsafe { match u { MyUnion { f1: 10 } => { } MyUnion { f2 } => { panic!("foo"); } } } }