@@ -12,6 +12,7 @@ use std::cell::RefCell;
12
12
use std:: future:: Future ;
13
13
use std:: marker:: PhantomData ;
14
14
use std:: sync:: Arc ;
15
+ use std:: rc:: Rc ;
15
16
use std:: task:: Context ;
16
17
17
18
struct EmptyWaker ;
@@ -26,45 +27,59 @@ enum DropOrder {
26
27
Val ( & ' static str ) ,
27
28
}
28
29
29
- struct D ( & ' static str , Arc < RefCell < Vec < DropOrder > > > ) ;
30
+ type DropOrderListPtr = Rc < RefCell < Vec < DropOrder > > > ;
31
+
32
+ struct D ( & ' static str , DropOrderListPtr ) ;
30
33
31
34
impl Drop for D {
32
35
fn drop ( & mut self ) {
33
36
self . 1 . borrow_mut ( ) . push ( DropOrder :: Val ( self . 0 ) ) ;
34
37
}
35
38
}
36
39
40
+ /// Check that unused bindings are dropped after the function is polled.
37
41
async fn foo ( x : D , _y : D ) {
38
42
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
39
43
}
40
44
45
+ /// Check that underscore patterns are dropped after the function is polled.
41
46
async fn bar ( x : D , _: D ) {
42
47
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
43
48
}
44
49
50
+ /// Check that underscore patterns within more complex patterns are dropped after the function
51
+ /// is polled.
45
52
async fn baz ( ( x, _) : ( D , D ) ) {
46
53
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
47
54
}
48
55
56
+ /// Check that underscore and unused bindings within and outwith more complex patterns are dropped
57
+ /// after the function is polled.
49
58
async fn foobar ( x : D , ( a, _, _c) : ( D , D , D ) , _: D , _y : D ) {
50
59
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
51
60
}
52
61
53
62
struct Foo ;
54
63
55
64
impl Foo {
65
+ /// Check that unused bindings are dropped after the method is polled.
56
66
async fn foo ( x : D , _y : D ) {
57
67
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
58
68
}
59
69
70
+ /// Check that underscore patterns are dropped after the method is polled.
60
71
async fn bar ( x : D , _: D ) {
61
72
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
62
73
}
63
74
75
+ /// Check that underscore patterns within more complex patterns are dropped after the method
76
+ /// is polled.
64
77
async fn baz ( ( x, _) : ( D , D ) ) {
65
78
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
66
79
}
67
80
81
+ /// Check that underscore and unused bindings within and outwith more complex patterns are
82
+ /// dropped after the method is polled.
68
83
async fn foobar ( x : D , ( a, _, _c) : ( D , D , D ) , _: D , _y : D ) {
69
84
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
70
85
}
@@ -73,120 +88,97 @@ impl Foo {
73
88
struct Bar < ' a > ( PhantomData < & ' a ( ) > ) ;
74
89
75
90
impl < ' a > Bar < ' a > {
91
+ /// Check that unused bindings are dropped after the method with self is polled.
76
92
async fn foo ( & ' a self , x : D , _y : D ) {
77
93
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
78
94
}
79
95
96
+ /// Check that underscore patterns are dropped after the method with self is polled.
80
97
async fn bar ( & ' a self , x : D , _: D ) {
81
98
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
82
99
}
83
100
101
+ /// Check that underscore patterns within more complex patterns are dropped after the method
102
+ /// with self is polled.
84
103
async fn baz ( & ' a self , ( x, _) : ( D , D ) ) {
85
104
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
86
105
}
87
106
107
+ /// Check that underscore and unused bindings within and outwith more complex patterns are
108
+ /// dropped after the method with self is polled.
88
109
async fn foobar ( & ' a self , x : D , ( a, _, _c) : ( D , D , D ) , _: D , _y : D ) {
89
110
x. 1 . borrow_mut ( ) . push ( DropOrder :: Function ) ;
90
111
}
91
112
}
92
113
93
- fn main ( ) {
114
+ fn assert_drop_order_after_poll < Fut : Future < Output = ( ) > > (
115
+ f : impl FnOnce ( DropOrderListPtr ) -> Fut ,
116
+ expected_order : & [ DropOrder ] ,
117
+ ) {
94
118
let empty = Arc :: new ( EmptyWaker ) ;
95
119
let waker = ArcWake :: into_waker ( empty) ;
96
120
let mut cx = Context :: from_waker ( & waker) ;
97
121
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 ( ) ) ) ;
137
124
let _ = fut. as_mut ( ) . poll ( & mut cx) ;
138
- assert_eq ! ( * af. borrow( ) , & [ Function , Val ( "_y" ) , Val ( "x" ) ] ) ;
139
125
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
+ }
161
128
162
- // Methods
129
+ fn main ( ) {
130
+ use DropOrder :: * ;
163
131
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).
164
169
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 ( "_" ) ] ) ;
192
184
}
0 commit comments