Skip to content

[wg-async-await] Drop async fn arguments in async block #59135

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add test for drop order in async functions.
This tests that async functions drop parameters in the same order as
regular functions.
  • Loading branch information
davidtwco committed Mar 24, 2019
commit 5ce3540c3879c66fc3debe3e67146c4e44826fa3
87 changes: 87 additions & 0 deletions src/test/run-pass/issue-54716.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// aux-build:arc_wake.rs
// edition:2018
// run-pass

#![allow(unused_variables)]
#![feature(async_await, await_macro, futures_api)]

extern crate arc_wake;

use arc_wake::ArcWake;
use std::cell::RefCell;
use std::future::Future;
use std::sync::Arc;

struct EmptyWaker;

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

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

struct D(&'static str, Arc<RefCell<Vec<DropOrder>>>);

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

async fn foo(x: D, _y: D) {
x.1.borrow_mut().push(DropOrder::Function);
}

async fn bar(x: D, _: D) {
x.1.borrow_mut().push(DropOrder::Function);
}

async fn baz((x, _): (D, D)) {
x.1.borrow_mut().push(DropOrder::Function);
}

async fn foobar(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
x.1.borrow_mut().push(DropOrder::Function);
}

fn main() {
let empty = Arc::new(EmptyWaker);
let waker = ArcWake::into_waker(empty);

use DropOrder::*;

// Currently, the `bar` and `foobar` tests do not output the same order as the equivalent
// non-async functions. This is because the drop order of captured variables doesn't match the
// drop order of arguments in a function.

let af = Arc::new(RefCell::new(Vec::new()));
let mut fut = Box::pin(foo(D("x", af.clone()), D("_y", af.clone())));
let _ = fut.as_mut().poll(&waker);
assert_eq!(*af.borrow(), &[Function, Val("_y"), Val("x")]);

let af = Arc::new(RefCell::new(Vec::new()));
let mut fut = Box::pin(bar(D("x", af.clone()), D("_", af.clone())));
let _ = fut.as_mut().poll(&waker);
assert_eq!(*af.borrow(), &[Function, Val("x"), Val("_")]);

let af = Arc::new(RefCell::new(Vec::new()));
let mut fut = Box::pin(baz((D("x", af.clone()), D("_", af.clone()))));
let _ = fut.as_mut().poll(&waker);
assert_eq!(*af.borrow(), &[Function, Val("x"), Val("_")]);

let af = Arc::new(RefCell::new(Vec::new()));
let mut fut = Box::pin(foobar(
D("x", af.clone()),
(D("a", af.clone()), D("_", af.clone()), D("_c", af.clone())),
D("_", af.clone()),
D("_y", af.clone()),
));
let _ = fut.as_mut().poll(&waker);
assert_eq!(*af.borrow(), &[
Function, Val("_y"), Val("_c"), Val("a"), Val("x"), Val("_"), Val("_"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should name these _1 etc?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to have the names here match the function arguments as I found that was easier to reason about when there was a failure. So, _1 could be used for the argument names, but I'd still need to use something non-numeric for the bindings that don't start with _ which would be inconsistent.

]);
}