@@ -3,35 +3,49 @@ use std::future::Future;
33// This test:
44// - Compares addresses of non-Copy data before and after moving it
55// - 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
611async 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+ }
728 // Vec<T> is not Copy
829 let mut x: Vec < u8 > = vec ! [ 2 ] ;
930 let raw_pointer = & mut x as * mut Vec < u8 > ;
10- helper_async ( x, raw_pointer) . await ;
31+ helper ( x, raw_pointer) . await ;
1132 unsafe {
1233 assert_eq ! ( * raw_pointer, vec![ 3 ] ) ;
1334 // Drop to prevent leak.
1435 std:: ptr:: drop_in_place ( raw_pointer) ;
1536 }
1637}
1738
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-
3339// Same thing as above, but non-async.
3440fn 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+
3549 let mut x: Vec < u8 > = vec ! [ 2 ] ;
3650 let raw_pointer = & mut x as * mut Vec < u8 > ;
3751 helper ( x, raw_pointer) ;
@@ -41,15 +55,6 @@ fn data_moved() {
4155 }
4256}
4357
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-
5358fn run_fut < T > ( fut : impl Future < Output = T > ) -> T {
5459 use std:: sync:: Arc ;
5560 use std:: task:: { Context , Poll , Wake , Waker } ;
0 commit comments