89 lines
1.6 KiB
Rust
89 lines
1.6 KiB
Rust
|
#![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: 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"); }
|
||
|
}
|
||
|
}
|
||
|
}
|