// aux-build:arc_wake.rs
// edition:2018
// run-pass

#![deny(dead_code)]

// Test that the drop order for locals in a fn and async fn matches up.
extern crate arc_wake;

use arc_wake::ArcWake;
use std::cell::RefCell;
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::rc::Rc;
use std::sync::Arc;
use std::task::{Context, Poll};

struct EmptyWaker;

impl ArcWake for EmptyWaker {
    fn wake(self: Arc<Self>) {}
}

#[derive(Debug, Eq, PartialEq)]
enum DropOrder {
    Function,
    Val(&'static str),
}

type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;

struct D(&'static str, DropOrderListPtr);

impl Drop for D {
    fn drop(&mut self) {
        self.1.borrow_mut().push(DropOrder::Val(self.0));
    }
}

struct NeverReady;

impl Future for NeverReady {
    type Output = ();
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
        Poll::Pending
    }
}

async fn simple_variable_declaration_async(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    NeverReady.await;
}

fn simple_variable_declaration_sync(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
}

async fn varable_completely_contained_within_block_async(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    async {
        let x = D("x", l.clone());
    }
        .await;
    let y = D("y", l.clone());
    NeverReady.await;
}

fn varable_completely_contained_within_block_sync(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    {
        let x = D("x", l.clone());
    }
    let y = D("y", l.clone());
}

async fn variables_moved_into_separate_blocks_async(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    async move { x }.await;
    async move { y }.await;
    NeverReady.await;
}

fn variables_moved_into_separate_blocks_sync(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    {
        x
    };
    {
        y
    };
}

async fn variables_moved_into_same_block_async(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    async move {
        x;
        y;
    };
    NeverReady.await;
}

fn variables_moved_into_same_block_sync(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    {
        x;
        y;
    };
    return;
}

async fn move_after_current_await_doesnt_affect_order(l: DropOrderListPtr) {
    l.borrow_mut().push(DropOrder::Function);
    let x = D("x", l.clone());
    let y = D("y", l.clone());
    NeverReady.await;
    async move {
        x;
        y;
    };
}

fn assert_drop_order_after_cancel<Fut: Future<Output = ()>>(
    f: impl FnOnce(DropOrderListPtr) -> Fut,
    g: impl FnOnce(DropOrderListPtr),
) {
    let empty = Arc::new(EmptyWaker);
    let waker = ArcWake::into_waker(empty);
    let mut cx = Context::from_waker(&waker);

    let actual_order = Rc::new(RefCell::new(Vec::new()));
    let mut fut = Box::pin(f(actual_order.clone()));
    let _ = fut.as_mut().poll(&mut cx);
    drop(fut);

    let expected_order = Rc::new(RefCell::new(Vec::new()));
    g(expected_order.clone());
    assert_eq!(*actual_order.borrow(), *expected_order.borrow());
}

fn main() {
    assert_drop_order_after_cancel(
        simple_variable_declaration_async,
        simple_variable_declaration_sync,
    );
    assert_drop_order_after_cancel(
        varable_completely_contained_within_block_async,
        varable_completely_contained_within_block_sync,
    );
    assert_drop_order_after_cancel(
        variables_moved_into_separate_blocks_async,
        variables_moved_into_separate_blocks_sync,
    );
    assert_drop_order_after_cancel(
        variables_moved_into_same_block_async,
        variables_moved_into_same_block_sync,
    );
    assert_drop_order_after_cancel(
        move_after_current_await_doesnt_affect_order,
        simple_variable_declaration_sync,
    );
}
