diff --git a/src/test/ui/async-await/move-part-await-return-rest-struct.rs b/src/test/ui/async-await/move-part-await-return-rest-struct.rs new file mode 100644 index 0000000000000..9bd7a515cbdbf --- /dev/null +++ b/src/test/ui/async-await/move-part-await-return-rest-struct.rs @@ -0,0 +1,20 @@ +// build-pass +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +struct Small { + x: Vec, + y: Vec, +} + +// You are allowed to move out part of a struct to an async fn, you still +// have access to remaining parts after awaiting +async fn move_part_await_return_rest_struct() -> Vec { + let s = Small { x: vec![31], y: vec![19, 1441] }; + needs_vec(s.x).await; + s.y +} + +async fn needs_vec(_vec: Vec) {} diff --git a/src/test/ui/async-await/move-part-await-return-rest-tuple.rs b/src/test/ui/async-await/move-part-await-return-rest-tuple.rs new file mode 100644 index 0000000000000..69eee855e7594 --- /dev/null +++ b/src/test/ui/async-await/move-part-await-return-rest-tuple.rs @@ -0,0 +1,14 @@ +// build-pass +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +async fn move_part_await_return_rest_tuple() -> Vec { + let x = (vec![3], vec![4, 4]); + drop(x.1); + echo(x.0[0]).await; + x.0 +} + +async fn echo(x: usize) -> usize { x } diff --git a/src/test/ui/async-await/no-move-across-await-struct.rs b/src/test/ui/async-await/no-move-across-await-struct.rs new file mode 100644 index 0000000000000..58e094708979c --- /dev/null +++ b/src/test/ui/async-await/no-move-across-await-struct.rs @@ -0,0 +1,19 @@ +// compile-fail +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +async fn no_move_across_await_struct() -> Vec { + let s = Small { x: vec![31], y: vec![19, 1441] }; + needs_vec(s.x).await; + s.x + //~^ ERROR use of moved value: `s.x` +} + +struct Small { + x: Vec, + y: Vec, +} + +async fn needs_vec(_vec: Vec) {} diff --git a/src/test/ui/async-await/no-move-across-await-struct.stderr b/src/test/ui/async-await/no-move-across-await-struct.stderr new file mode 100644 index 0000000000000..121c7791bd98e --- /dev/null +++ b/src/test/ui/async-await/no-move-across-await-struct.stderr @@ -0,0 +1,13 @@ +error[E0382]: use of moved value: `s.x` + --> $DIR/no-move-across-await-struct.rs:10:5 + | +LL | needs_vec(s.x).await; + | --- value moved here +LL | s.x + | ^^^ value used here after move + | + = note: move occurs because `s.x` has type `std::vec::Vec`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/async-await/no-move-across-await-tuple.rs b/src/test/ui/async-await/no-move-across-await-tuple.rs new file mode 100644 index 0000000000000..5d3ed3da1e316 --- /dev/null +++ b/src/test/ui/async-await/no-move-across-await-tuple.rs @@ -0,0 +1,15 @@ +// compile-fail +// edition:2018 +// compile-flags: --crate-type lib + +#![feature(async_await)] + +async fn no_move_across_await_tuple() -> Vec { + let x = (vec![3], vec![4, 4]); + drop(x.1); + nothing().await; + x.1 + //~^ ERROR use of moved value: `x.1` +} + +async fn nothing() {} diff --git a/src/test/ui/async-await/no-move-across-await-tuple.stderr b/src/test/ui/async-await/no-move-across-await-tuple.stderr new file mode 100644 index 0000000000000..5da037ea5c0b6 --- /dev/null +++ b/src/test/ui/async-await/no-move-across-await-tuple.stderr @@ -0,0 +1,14 @@ +error[E0382]: use of moved value: `x.1` + --> $DIR/no-move-across-await-tuple.rs:11:5 + | +LL | drop(x.1); + | --- value moved here +LL | nothing().await; +LL | x.1 + | ^^^ value used here after move + | + = note: move occurs because `x.1` has type `std::vec::Vec`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`.