unsafe fn unsafe_fn() {}

union Union {
    a: u32,
    b: f32,
}

struct HasUnsafeFn;

impl HasUnsafeFn {
    unsafe fn unsafe_method(&self) {}
}

struct TypeForStaticMut {
    a: u8
}

static mut global_mut: TypeForStaticMut = TypeForStaticMut { a: 0 };

#[repr(packed)]
struct Packed {
    a: u16,
}

unsafe trait UnsafeTrait {}
unsafe impl UnsafeTrait for Packed {}

fn require_unsafe_trait<T: UnsafeTrait>(_: T) {}

trait DoTheAutoref {
    fn calls_autoref(&self);
}

impl DoTheAutoref for u16 {
    fn calls_autoref(&self) {}
}

fn main() {
    let x = &5 as *const _ as *const usize;
    let u = Union { b: 0 };
    unsafe {
        // unsafe fn and method calls
        unsafe_fn();
        let b = u.b;
        match u {
            Union { b: 0 } => (),
            Union { a } => (),
        }
        HasUnsafeFn.unsafe_method();

        // unsafe deref
        let y = *x;

        // unsafe access to a static mut
        let a = global_mut.a;

        // unsafe ref of packed fields
        let packed = Packed { a: 0 };
        let a = &packed.a;
        let ref a = packed.a;
        let Packed { ref a } = packed;
        let Packed { a: ref _a } = packed;

        // unsafe auto ref of packed field
        packed.a.calls_autoref();
    }
}