@@ -12,6 +12,7 @@ use std::cell::RefCell;
1212use std:: future:: Future ;
1313use std:: marker:: PhantomData ;
1414use std:: sync:: Arc ;
15+ use std:: rc:: Rc ;
1516use std:: task:: Context ;
1617
1718struct EmptyWaker ;
@@ -26,45 +27,59 @@ enum DropOrder {
2627 Val ( & ' static str ) ,
2728}
2829
29- struct D ( & ' static str , Arc < RefCell < Vec < DropOrder > > > ) ;
30+ type DropOrderListPtr = Rc < RefCell < Vec < DropOrder > > > ;
31+
32+ struct D ( & ' static str , DropOrderListPtr ) ;
3033
3134impl Drop for D {
3235 fn drop ( & mut self ) {
3336 self . 1 . borrow_mut ( ) . push ( DropOrder :: Val ( self . 0 ) ) ;
3437 }
3538}
3639
40+ /// Check that unused bindings are dropped after the function is polled.
3741async fn foo ( x : D , _y : D ) {
3842 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
3943}
4044
45+ /// Check that underscore patterns are dropped after the function is polled.
4146async fn bar ( x : D , _: D ) {
4247 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
4348}
4449
50+ /// Check that underscore patterns within more complex patterns are dropped after the function
51+ /// is polled.
4552async fn baz ( ( x, _) : ( D , D ) ) {
4653 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
4754}
4855
56+ /// Check that underscore and unused bindings within and outwith more complex patterns are dropped
57+ /// after the function is polled.
4958async fn foobar ( x : D , ( a, _, _c) : ( D , D , D ) , _: D , _y : D ) {
5059 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
5160}
5261
5362struct Foo ;
5463
5564impl Foo {
65+ /// Check that unused bindings are dropped after the method is polled.
5666 async fn foo ( x : D , _y : D ) {
5767 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
5868 }
5969
70+ /// Check that underscore patterns are dropped after the method is polled.
6071 async fn bar ( x : D , _: D ) {
6172 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
6273 }
6374
75+ /// Check that underscore patterns within more complex patterns are dropped after the method
76+ /// is polled.
6477 async fn baz ( ( x, _) : ( D , D ) ) {
6578 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
6679 }
6780
81+ /// Check that underscore and unused bindings within and outwith more complex patterns are
82+ /// dropped after the method is polled.
6883 async fn foobar ( x : D , ( a, _, _c) : ( D , D , D ) , _: D , _y : D ) {
6984 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
7085 }
@@ -73,120 +88,97 @@ impl Foo {
7388struct Bar < ' a > ( PhantomData < & ' a ( ) > ) ;
7489
7590impl < ' a > Bar < ' a > {
91+ /// Check that unused bindings are dropped after the method with self is polled.
7692 async fn foo ( & ' a self , x : D , _y : D ) {
7793 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
7894 }
7995
96+ /// Check that underscore patterns are dropped after the method with self is polled.
8097 async fn bar ( & ' a self , x : D , _: D ) {
8198 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
8299 }
83100
101+ /// Check that underscore patterns within more complex patterns are dropped after the method
102+ /// with self is polled.
84103 async fn baz ( & ' a self , ( x, _) : ( D , D ) ) {
85104 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
86105 }
87106
107+ /// Check that underscore and unused bindings within and outwith more complex patterns are
108+ /// dropped after the method with self is polled.
88109 async fn foobar ( & ' a self , x : D , ( a, _, _c) : ( D , D , D ) , _: D , _y : D ) {
89110 x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
90111 }
91112}
92113
93- fn main ( ) {
114+ fn assert_drop_order_after_poll < Fut : Future < Output = ( ) > > (
115+ f : impl FnOnce ( DropOrderListPtr ) -> Fut ,
116+ expected_order : & [ DropOrder ] ,
117+ ) {
94118 let empty = Arc :: new ( EmptyWaker ) ;
95119 let waker = ArcWake :: into_waker ( empty) ;
96120 let mut cx = Context :: from_waker ( & waker) ;
97121
98- use DropOrder :: * ;
99-
100- // Currently, the `bar` and `foobar` tests do not output the same order as the equivalent
101- // non-async functions. This is because the drop order of captured variables doesn't match the
102- // drop order of arguments in a function.
103-
104- // Free functions
105-
106- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
107- let mut fut = Box :: pin ( foo ( D ( "x" , af. clone ( ) ) , D ( "_y" , af. clone ( ) ) ) ) ;
108- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
109- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "_y" ) , Val ( "x" ) ] ) ;
110-
111- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
112- let mut fut = Box :: pin ( bar ( D ( "x" , af. clone ( ) ) , D ( "_" , af. clone ( ) ) ) ) ;
113- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
114- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
115-
116- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
117- let mut fut = Box :: pin ( baz ( ( D ( "x" , af. clone ( ) ) , D ( "_" , af. clone ( ) ) ) ) ) ;
118- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
119- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
120-
121- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
122- let mut fut = Box :: pin ( foobar (
123- D ( "x" , af. clone ( ) ) ,
124- ( D ( "a" , af. clone ( ) ) , D ( "_" , af. clone ( ) ) , D ( "_c" , af. clone ( ) ) ) ,
125- D ( "_" , af. clone ( ) ) ,
126- D ( "_y" , af. clone ( ) ) ,
127- ) ) ;
128- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
129- assert_eq ! ( * af. borrow( ) , & [
130- Function , Val ( "_y" ) , Val ( "_c" ) , Val ( "a" ) , Val ( "x" ) , Val ( "_" ) , Val ( "_" ) ,
131- ] ) ;
132-
133- // Methods w/out self
134-
135- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
136- let mut fut = Box :: pin ( Foo :: foo ( D ( "x" , af. clone ( ) ) , D ( "_y" , af. clone ( ) ) ) ) ;
122+ let actual_order = Rc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
123+ let mut fut = Box :: pin ( f ( actual_order. clone ( ) ) ) ;
137124 let _ = fut. as_mut ( ) . poll ( & mut cx) ;
138- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "_y" ) , Val ( "x" ) ] ) ;
139125
140- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
141- let mut fut = Box :: pin ( Foo :: bar ( D ( "x" , af. clone ( ) ) , D ( "_" , af. clone ( ) ) ) ) ;
142- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
143- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
144-
145- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
146- let mut fut = Box :: pin ( Foo :: baz ( ( D ( "x" , af. clone ( ) ) , D ( "_" , af. clone ( ) ) ) ) ) ;
147- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
148- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
149-
150- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
151- let mut fut = Box :: pin ( Foo :: foobar (
152- D ( "x" , af. clone ( ) ) ,
153- ( D ( "a" , af. clone ( ) ) , D ( "_" , af. clone ( ) ) , D ( "_c" , af. clone ( ) ) ) ,
154- D ( "_" , af. clone ( ) ) ,
155- D ( "_y" , af. clone ( ) ) ,
156- ) ) ;
157- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
158- assert_eq ! ( * af. borrow( ) , & [
159- Function , Val ( "_y" ) , Val ( "_c" ) , Val ( "a" ) , Val ( "x" ) , Val ( "_" ) , Val ( "_" ) ,
160- ] ) ;
126+ assert_eq ! ( * actual_order. borrow( ) , expected_order) ;
127+ }
161128
162- // Methods
129+ fn main ( ) {
130+ use DropOrder :: * ;
163131
132+ // At time of writing (23/04/19), the `bar` and `foobar` tests do not output the same order as
133+ // the equivalent non-async functions. This is because the drop order of captured variables
134+ // doesn't match the drop order of arguments in a function.
135+
136+ // Free functions (see doc comment on function for what it tests).
137+ assert_drop_order_after_poll ( |l| foo ( D ( "x" , l. clone ( ) ) , D ( "_y" , l. clone ( ) ) ) ,
138+ & [ Function , Val ( "_y" ) , Val ( "x" ) ] ) ;
139+ assert_drop_order_after_poll ( |l| bar ( D ( "x" , l. clone ( ) ) , D ( "_" , l. clone ( ) ) ) ,
140+ & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
141+ assert_drop_order_after_poll ( |l| baz ( ( D ( "x" , l. clone ( ) ) , D ( "_" , l. clone ( ) ) ) ) ,
142+ & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
143+ assert_drop_order_after_poll ( |l| {
144+ foobar (
145+ D ( "x" , l. clone ( ) ) ,
146+ ( D ( "a" , l. clone ( ) ) , D ( "_" , l. clone ( ) ) , D ( "_c" , l. clone ( ) ) ) ,
147+ D ( "_" , l. clone ( ) ) ,
148+ D ( "_y" , l. clone ( ) ) ,
149+ )
150+ } , & [ Function , Val ( "_y" ) , Val ( "_c" ) , Val ( "a" ) , Val ( "x" ) , Val ( "_" ) , Val ( "_" ) ] ) ;
151+
152+ // Methods w/out self (see doc comment on function for what it tests).
153+ assert_drop_order_after_poll ( |l| Foo :: foo ( D ( "x" , l. clone ( ) ) , D ( "_y" , l. clone ( ) ) ) ,
154+ & [ Function , Val ( "_y" ) , Val ( "x" ) ] ) ;
155+ assert_drop_order_after_poll ( |l| Foo :: bar ( D ( "x" , l. clone ( ) ) , D ( "_" , l. clone ( ) ) ) ,
156+ & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
157+ assert_drop_order_after_poll ( |l| Foo :: baz ( ( D ( "x" , l. clone ( ) ) , D ( "_" , l. clone ( ) ) ) ) ,
158+ & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
159+ assert_drop_order_after_poll ( |l| {
160+ Foo :: foobar (
161+ D ( "x" , l. clone ( ) ) ,
162+ ( D ( "a" , l. clone ( ) ) , D ( "_" , l. clone ( ) ) , D ( "_c" , l. clone ( ) ) ) ,
163+ D ( "_" , l. clone ( ) ) ,
164+ D ( "_y" , l. clone ( ) ) ,
165+ )
166+ } , & [ Function , Val ( "_y" ) , Val ( "_c" ) , Val ( "a" ) , Val ( "x" ) , Val ( "_" ) , Val ( "_" ) ] ) ;
167+
168+ // Methods (see doc comment on function for what it tests).
164169 let b = Bar ( Default :: default ( ) ) ;
165-
166- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
167- let mut fut = Box :: pin ( b. foo ( D ( "x" , af. clone ( ) ) , D ( "_y" , af. clone ( ) ) ) ) ;
168- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
169- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "_y" ) , Val ( "x" ) ] ) ;
170-
171- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
172- let mut fut = Box :: pin ( b. bar ( D ( "x" , af. clone ( ) ) , D ( "_" , af. clone ( ) ) ) ) ;
173- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
174- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
175-
176- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
177- let mut fut = Box :: pin ( b. baz ( ( D ( "x" , af. clone ( ) ) , D ( "_" , af. clone ( ) ) ) ) ) ;
178- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
179- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
180-
181- let af = Arc :: new ( RefCell :: new ( Vec :: new ( ) ) ) ;
182- let mut fut = Box :: pin ( b. foobar (
183- D ( "x" , af. clone ( ) ) ,
184- ( D ( "a" , af. clone ( ) ) , D ( "_" , af. clone ( ) ) , D ( "_c" , af. clone ( ) ) ) ,
185- D ( "_" , af. clone ( ) ) ,
186- D ( "_y" , af. clone ( ) ) ,
187- ) ) ;
188- let _ = fut. as_mut ( ) . poll ( & mut cx) ;
189- assert_eq ! ( * af. borrow( ) , & [
190- Function , Val ( "_y" ) , Val ( "_c" ) , Val ( "a" ) , Val ( "x" ) , Val ( "_" ) , Val ( "_" ) ,
191- ] ) ;
170+ assert_drop_order_after_poll ( |l| b. foo ( D ( "x" , l. clone ( ) ) , D ( "_y" , l. clone ( ) ) ) ,
171+ & [ Function , Val ( "_y" ) , Val ( "x" ) ] ) ;
172+ assert_drop_order_after_poll ( |l| b. bar ( D ( "x" , l. clone ( ) ) , D ( "_" , l. clone ( ) ) ) ,
173+ & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
174+ assert_drop_order_after_poll ( |l| b. baz ( ( D ( "x" , l. clone ( ) ) , D ( "_" , l. clone ( ) ) ) ) ,
175+ & [ Function , Val ( "x" ) , Val ( "_" ) ] ) ;
176+ assert_drop_order_after_poll ( |l| {
177+ b. foobar (
178+ D ( "x" , l. clone ( ) ) ,
179+ ( D ( "a" , l. clone ( ) ) , D ( "_" , l. clone ( ) ) , D ( "_c" , l. clone ( ) ) ) ,
180+ D ( "_" , l. clone ( ) ) ,
181+ D ( "_y" , l. clone ( ) ) ,
182+ )
183+ } , & [ Function , Val ( "_y" ) , Val ( "_c" ) , Val ( "a" ) , Val ( "x" ) , Val ( "_" ) , Val ( "_" ) ] ) ;
192184}
0 commit comments