macro_rules! id {
    ($($tt:tt)*) => {
        $($tt)*
    };
}
macro_rules! unsafe_deref {
    () => {
        *(&() as *const ())
    };
}
static mut MUT_GLOBAL: Struct = Struct { field: 0 };
static GLOBAL: Struct = Struct { field: 0 };
unsafe fn unsafe_fn() {}

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

struct Struct { field: i32 }
impl Struct {
    unsafe fn unsafe_method(&self) {}
}

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

unsafe trait UnsafeTrait {}
unsafe impl UnsafeTrait for Packed {}
impl !UnsafeTrait for () {}

fn unsafe_trait_bound<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 };

    id! {
        unsafe { unsafe_deref!() }
    };

    unsafe {
        unsafe_deref!();
        id! { unsafe_deref!() };

        // unsafe fn and method calls
        unsafe_fn();
        let b = u.b;
        match u {
            Union { b: 0 } => (),
            Union { a } => (),
        }
        Struct { field: 0 }.unsafe_method();

        // unsafe deref
        *x;

        // unsafe access to a static mut
        MUT_GLOBAL.field;
        GLOBAL.field;

        // 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();
    }
}