#![warn(rust_2018_idioms, single_use_lifetimes)]

use std::pin::Pin;

use pin_project::{pin_project, pinned_drop};

#[test]
fn safe_project() {
    #[pin_project(PinnedDrop)]
    pub struct Struct<'a> {
        was_dropped: &'a mut bool,
        #[pin]
        field: u8,
    }

    #[pinned_drop]
    impl PinnedDrop for Struct<'_> {
        fn drop(self: Pin<&mut Self>) {
            **self.project().was_dropped = true;
        }
    }

    let mut was_dropped = false;
    drop(Struct { was_dropped: &mut was_dropped, field: 42 });
    assert!(was_dropped);
}

#[test]
fn self_call() {
    #[pin_project(PinnedDrop)]
    pub struct S<T>(T);

    trait Trait {
        fn self_ref(&self) {}
        fn self_pin_ref(self: Pin<&Self>) {}
        fn self_mut(&mut self) {}
        fn self_pin_mut(self: Pin<&mut Self>) {}
        fn assoc_fn(_this: Pin<&mut Self>) {}
    }

    impl<T> Trait for S<T> {}

    #[pinned_drop]
    impl<T> PinnedDrop for S<T> {
        fn drop(mut self: Pin<&mut Self>) {
            self.self_ref();
            self.as_ref().self_pin_ref();
            self.self_mut();
            self.as_mut().self_pin_mut();
            Self::assoc_fn(self.as_mut());
            <Self>::assoc_fn(self.as_mut());
        }
    }
}

#[test]
fn self_ty() {
    #[pin_project(PinnedDrop)]
    pub struct Struct {
        pub f: (),
    }

    #[pinned_drop]
    impl PinnedDrop for Struct {
        #[allow(irrefutable_let_patterns)]
        #[allow(clippy::match_single_binding)]
        fn drop(mut self: Pin<&mut Self>) {
            // expr
            let _: Self = Self { f: () };

            // pat
            match *self {
                Self { f: () } => {}
            }
            if let Self { f: () } = *self {}
            let Self { f: () } = *self;
        }
    }

    #[pin_project(PinnedDrop)]
    pub struct TupleStruct(());

    #[pinned_drop]
    impl PinnedDrop for TupleStruct {
        #[allow(irrefutable_let_patterns)]
        fn drop(mut self: Pin<&mut Self>) {
            // expr
            let _: Self = Self(());

            // pat
            match *self {
                Self(_) => {}
            }
            if let Self(_) = *self {}
            let Self(_) = *self;
        }
    }

    #[pin_project(PinnedDrop, project = EnumProj, project_ref = EnumProjRef)]
    pub enum Enum {
        Struct { f: () },
        Tuple(()),
        Unit,
    }

    #[pinned_drop]
    impl PinnedDrop for Enum {
        fn drop(mut self: Pin<&mut Self>) {
            // expr
            let _: Self = Self::Struct { f: () };
            let _: Self = Self::Tuple(());
            let _: Self = Self::Unit;

            // pat
            match *self {
                Self::Struct { f: () } => {}
                Self::Tuple(_) => {}
                Self::Unit => {}
            }
            if let Self::Struct { f: () } = *self {}
            if let Self::Tuple(_) = *self {}
            if let Self::Unit = *self {}
        }
    }
}

#[test]
fn self_inside_macro_containing_fn() {
    macro_rules! mac {
        ($($tt:tt)*) => {
            $($tt)*
        };
    }

    #[pin_project(PinnedDrop)]
    pub struct S(());

    #[pinned_drop]
    impl PinnedDrop for S {
        fn drop(self: Pin<&mut Self>) {
            mac!({
                impl S {
                    pub fn _f(self) -> Self {
                        self
                    }
                }
            });
        }
    }
}

// See also `ui/pinned_drop/self.rs`.
#[test]
fn self_inside_macro_def() {
    #[pin_project(PinnedDrop)]
    pub struct S(());

    #[pinned_drop]
    impl PinnedDrop for S {
        fn drop(self: Pin<&mut Self>) {
            macro_rules! mac {
                () => {{
                    let _ = self;
                    let _ = Self(());
                }};
            }
            mac!();
        }
    }
}

#[test]
fn self_arg_inside_macro_call() {
    #[pin_project(PinnedDrop)]
    struct Struct {
        f: (),
    }

    #[pinned_drop]
    impl PinnedDrop for Struct {
        fn drop(self: Pin<&mut Self>) {
            let _: Vec<_> = vec![self.f];
        }
    }
}

#[test]
fn self_ty_inside_macro_call() {
    macro_rules! mac {
        ($($tt:tt)*) => {
            $($tt)*
        };
    }

    #[pin_project(PinnedDrop)]
    pub struct Struct<T: Send>
    where
        mac!(Self): Send,
    {
        _f: T,
    }

    impl<T: Send> Struct<T> {
        const ASSOC1: usize = 1;
        fn assoc1() {}
    }

    trait Trait {
        type Assoc2;
        const ASSOC2: usize;
        fn assoc2();
    }

    impl<T: Send> Trait for Struct<T> {
        type Assoc2 = u8;
        const ASSOC2: usize = 2;
        fn assoc2() {}
    }

    #[pinned_drop]
    impl<T: Send> PinnedDrop for Struct<T>
    where
        mac!(Self): Send,
    {
        #[allow(path_statements)]
        #[allow(clippy::no_effect)]
        fn drop(self: Pin<&mut Self>) {
            // inherent items
            mac!(Self::ASSOC1;);
            mac!(<Self>::ASSOC1;);
            mac!(Self::assoc1(););
            mac!(<Self>::assoc1(););

            // trait items
            mac!(let _: <Self as Trait>::Assoc2;);
            mac!(Self::ASSOC2;);
            mac!(<Self>::ASSOC2;);
            mac!(<Self as Trait>::ASSOC2;);
            mac!(Self::assoc2(););
            mac!(<Self>::assoc2(););
            mac!(<Self as Trait>::assoc2(););
        }
    }
}

#[test]
fn inside_macro() {
    #[pin_project(PinnedDrop)]
    struct S(());

    macro_rules! mac {
        ($expr:expr) => {
            #[pinned_drop]
            impl PinnedDrop for S {
                fn drop(self: Pin<&mut Self>) {
                    let _ = $expr;
                }
            }
        };
    }

    mac!(1);
}

pub mod self_path {
    use super::*;

    #[pin_project(PinnedDrop)]
    pub struct S<T: Unpin>(T);

    fn f() {}

    #[pinned_drop]
    impl<T: Unpin> PinnedDrop for self::S<T> {
        fn drop(mut self: Pin<&mut Self>) {
            self::f();
            let _: self::S<()> = self::S(());
            let _: self::S<Pin<&mut Self>> = self::S(self.as_mut());
            let self::S(()) = self::S(());
            let self::S(&mut Self(_)) = self::S(&mut *self);
        }
    }
}
