#![warn(clippy::unsafe_derive_deserialize)]
#![allow(unused, clippy::missing_safety_doc)]

extern crate serde;

use serde::Deserialize;

#[derive(Deserialize)]
//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe
pub struct A;
impl A {
    pub unsafe fn new(_a: i32, _b: i32) -> Self {
        Self {}
    }
}

#[derive(Deserialize)]
//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe
pub struct B;
impl B {
    pub unsafe fn unsafe_method(&self) {}
}

#[derive(Deserialize)]
//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe
pub struct C;
impl C {
    pub fn unsafe_block(&self) {
        unsafe {}
    }
}

#[derive(Deserialize)]
//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe
pub struct D;
impl D {
    pub fn inner_unsafe_fn(&self) {
        unsafe fn inner() {}
    }
}

// Does not derive `Deserialize`, should be ignored
pub struct E;
impl E {
    pub unsafe fn new(_a: i32, _b: i32) -> Self {
        Self {}
    }

    pub unsafe fn unsafe_method(&self) {}

    pub fn unsafe_block(&self) {
        unsafe {}
    }

    pub fn inner_unsafe_fn(&self) {
        unsafe fn inner() {}
    }
}

// Does not have methods using `unsafe`, should be ignored
#[derive(Deserialize)]
pub struct F;

// Check that we honor the `allow` attribute on the ADT
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Deserialize)]
pub struct G;
impl G {
    pub fn unsafe_block(&self) {
        unsafe {}
    }
}

// Check that we honor the `expect` attribute on the ADT
#[expect(clippy::unsafe_derive_deserialize)]
#[derive(Deserialize)]
pub struct H;
impl H {
    pub fn unsafe_block(&self) {
        unsafe {}
    }
}

fn main() {}
