@@ -3,35 +3,49 @@ use std::future::Future;
3
3
// This test:
4
4
// - Compares addresses of non-Copy data before and after moving it
5
5
// - Writes to the pointer after it has moved across the await point
6
+ //
7
+ // This is only meant to assert current behavior, not guarantee that this is
8
+ // how it should work in the future. In fact, upcoming changes to rustc
9
+ // *should* break these tests.
10
+ // See: https://github.com/rust-lang/rust/issues/62958
6
11
async fn data_moved_async ( ) {
12
+ async fn helper ( mut data : Vec < u8 > , raw_pointer : * mut Vec < u8 > ) {
13
+ let raw_pointer2 = & mut data as * mut Vec < u8 > ;
14
+ // When the Vec is moved into the generator upvar, that copies the Vec's
15
+ // ptr+capacity+len that is on the stack. Because of that, the value of
16
+ // `raw_pointer2` is different than that of `raw_pointer`.
17
+ //
18
+ // When copy propagation is enabled for generator upvars, the pointer
19
+ // addresses should be equal, becouse there will no longer be a
20
+ // generator upvar; instead, the function's `data` argument will be
21
+ // used directly.
22
+ assert_ne ! ( raw_pointer, raw_pointer2) ;
23
+ unsafe {
24
+ // This writes into the `x` in `data_moved_async`, re-initializing it.
25
+ std:: ptr:: write ( raw_pointer, vec ! [ 3 ] ) ;
26
+ }
27
+ }
7
28
// Vec<T> is not Copy
8
29
let mut x: Vec < u8 > = vec ! [ 2 ] ;
9
30
let raw_pointer = & mut x as * mut Vec < u8 > ;
10
- helper_async ( x, raw_pointer) . await ;
31
+ helper ( x, raw_pointer) . await ;
11
32
unsafe {
12
33
assert_eq ! ( * raw_pointer, vec![ 3 ] ) ;
13
34
// Drop to prevent leak.
14
35
std:: ptr:: drop_in_place ( raw_pointer) ;
15
36
}
16
37
}
17
38
18
- async fn helper_async ( mut data : Vec < u8 > , raw_pointer : * mut Vec < u8 > ) {
19
- let raw_pointer2 = & mut data as * mut Vec < u8 > ;
20
- // Addresses are different because the generator upvar for `data` is a copy.
21
- // To be more precise, there is a `move` happening in the MIR of the
22
- // generator closure, which copies the pointer.
23
- //
24
- // When copy propagation is enabled for generator upvars, the pointer addresses
25
- // here should be equal.
26
- assert_ne ! ( raw_pointer, raw_pointer2) ;
27
- unsafe {
28
- // This writes into the `x` in `data_moved_async`, re-initializing it.
29
- std:: ptr:: write ( raw_pointer, vec ! [ 3 ] ) ;
30
- }
31
- }
32
-
33
39
// Same thing as above, but non-async.
34
40
fn data_moved ( ) {
41
+ fn helper ( mut data : Vec < u8 > , raw_pointer : * mut Vec < u8 > ) {
42
+ let raw_pointer2 = & mut data as * mut Vec < u8 > ;
43
+ assert_ne ! ( raw_pointer, raw_pointer2) ;
44
+ unsafe {
45
+ std:: ptr:: write ( raw_pointer, vec ! [ 3 ] ) ;
46
+ }
47
+ }
48
+
35
49
let mut x: Vec < u8 > = vec ! [ 2 ] ;
36
50
let raw_pointer = & mut x as * mut Vec < u8 > ;
37
51
helper ( x, raw_pointer) ;
@@ -41,15 +55,6 @@ fn data_moved() {
41
55
}
42
56
}
43
57
44
- #[ inline( always) ]
45
- fn helper ( mut data : Vec < u8 > , raw_pointer : * mut Vec < u8 > ) {
46
- let raw_pointer2 = & mut data as * mut Vec < u8 > ;
47
- assert_ne ! ( raw_pointer, raw_pointer2) ;
48
- unsafe {
49
- std:: ptr:: write ( raw_pointer, vec ! [ 3 ] ) ;
50
- }
51
- }
52
-
53
58
fn run_fut < T > ( fut : impl Future < Output = T > ) -> T {
54
59
use std:: sync:: Arc ;
55
60
use std:: task:: { Context , Poll , Wake , Waker } ;
0 commit comments