Skip to content

Commit c9b4846

Browse files
committed
Update based on feedback
- Add/revise comments - Move helper functions inside the functions being tested - Remove `inline` annotation for non-async case to make it more similar to the async case
1 parent b4f9c16 commit c9b4846

File tree

1 file changed

+30
-25
lines changed

1 file changed

+30
-25
lines changed

tests/pass/move-data-across-await-point.rs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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
611
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+
}
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.
3440
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+
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-
5358
fn 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

Comments
 (0)