diff options
| author | Tyler Mandry <tmandry@gmail.com> | 2020-03-24 17:23:50 -0700 |
|---|---|---|
| committer | Tyler Mandry <tmandry@gmail.com> | 2020-04-13 18:48:55 -0700 |
| commit | a40ec132621225f3d7e373d6630eb45f862fe39b (patch) | |
| tree | 568f354669a0500a4f5e53975c0dc2686fef2837 | |
| parent | b129b32afa3fa896f1464b9a529c30116a7a4e5c (diff) | |
| download | rust-a40ec132621225f3d7e373d6630eb45f862fe39b.tar.gz rust-a40ec132621225f3d7e373d6630eb45f862fe39b.zip | |
Add test for #68112 (existing output)
| -rw-r--r-- | src/test/ui/async-await/issue-68112.rs | 53 | ||||
| -rw-r--r-- | src/test/ui/async-await/issue-68112.stderr | 45 | ||||
| -rw-r--r-- | src/test/ui/generator/issue-68112.rs | 56 | ||||
| -rw-r--r-- | src/test/ui/generator/issue-68112.stderr | 40 |
4 files changed, 194 insertions, 0 deletions
diff --git a/src/test/ui/async-await/issue-68112.rs b/src/test/ui/async-await/issue-68112.rs new file mode 100644 index 00000000000..0d269b1801b --- /dev/null +++ b/src/test/ui/async-await/issue-68112.rs @@ -0,0 +1,53 @@ +// edition:2018 + +use std::{ + future::Future, + cell::RefCell, + sync::Arc, + pin::Pin, + task::{Context, Poll}, +}; + +fn require_send(_: impl Send) {} + +struct Ready<T>(Option<T>); +impl<T> Future for Ready<T> { + type Output = T; + fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> { + Poll::Ready(self.0.take().unwrap()) + } +} +fn ready<T>(t: T) -> Ready<T> { + Ready(Some(t)) +} + +fn make_non_send_future1() -> impl Future<Output = Arc<RefCell<i32>>> { + ready(Arc::new(RefCell::new(0))) +} + +fn test1() { + let send_fut = async { + let non_send_fut = make_non_send_future1(); + let _ = non_send_fut.await; + ready(0).await; + }; + require_send(send_fut); + //~^ ERROR future cannot be sent between threads +} + +async fn ready2<T>(t: T) -> T { t } +fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> { + ready2(Arc::new(RefCell::new(0))) +} + +fn test2() { + let send_fut = async { + let non_send_fut = make_non_send_future2(); + let _ = non_send_fut.await; + ready(0).await; + }; + require_send(send_fut); + //~^ ERROR `std::cell::RefCell<i32>` cannot be shared between threads safely +} + +fn main() {} diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr new file mode 100644 index 00000000000..461967b7d8b --- /dev/null +++ b/src/test/ui/async-await/issue-68112.stderr @@ -0,0 +1,45 @@ +error: future cannot be sent between threads safely + --> $DIR/issue-68112.rs:34:5 + | +LL | fn require_send(_: impl Send) {} + | ------------ ---- required by this bound in `require_send` +... +LL | require_send(send_fut); + | ^^^^^^^^^^^^ future returned by `test1` is not `Send` + | + = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>` +note: future is not `Send` as this value is used across an await + --> $DIR/issue-68112.rs:32:9 + | +LL | let non_send_fut = make_non_send_future1(); + | ------------ has type `impl std::future::Future` +LL | let _ = non_send_fut.await; +LL | ready(0).await; + | ^^^^^^^^ await occurs here, with `non_send_fut` maybe used later +LL | }; + | - `non_send_fut` is later dropped here + +error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely + --> $DIR/issue-68112.rs:49:5 + | +LL | fn require_send(_: impl Send) {} + | ------------ ---- required by this bound in `require_send` +... +LL | require_send(send_fut); + | ^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>` + = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::cell::RefCell<i32>>` + = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:38:31: 38:36 t:std::sync::Arc<std::cell::RefCell<i32>> {}]` + = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:38:31: 38:36 t:std::sync::Arc<std::cell::RefCell<i32>> {}]>` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `{std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}` + = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:44:26: 48:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]` + = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:44:26: 48:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]>` + = note: required because it appears within the type `impl std::future::Future` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/issue-68112.rs b/src/test/ui/generator/issue-68112.rs new file mode 100644 index 00000000000..ee62cbff08f --- /dev/null +++ b/src/test/ui/generator/issue-68112.rs @@ -0,0 +1,56 @@ +#![feature(generators, generator_trait)] + +use std::{ + cell::RefCell, + sync::Arc, + pin::Pin, + ops::{Generator, GeneratorState}, +}; + +pub struct Ready<T>(Option<T>); +impl<T> Generator<()> for Ready<T> { + type Return = T; + type Yield = (); + fn resume(mut self: Pin<&mut Self>, _args: ()) -> GeneratorState<(), T> { + GeneratorState::Complete(self.0.take().unwrap()) + } +} +pub fn make_gen1<T>(t: T) -> Ready<T> { + Ready(Some(t)) +} + +fn require_send(_: impl Send) {} + +fn make_non_send_generator() -> impl Generator<Return = Arc<RefCell<i32>>> { + make_gen1(Arc::new(RefCell::new(0))) +} + +fn test1() { + let send_gen = || { + let _non_send_gen = make_non_send_generator(); + yield; + }; + require_send(send_gen); + //~^ ERROR future cannot be sent between threads +} + +pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> { + || { + yield; + t + } +} +fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> { + make_gen2(Arc::new(RefCell::new(0))) +} + +fn test2() { + let send_gen = || { + let _non_send_gen = make_non_send_generator2(); + yield; + }; + require_send(send_gen); + //~^ ERROR `std::cell::RefCell<i32>` cannot be shared between threads safely +} + +fn main() {} diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr new file mode 100644 index 00000000000..b98afd47b56 --- /dev/null +++ b/src/test/ui/generator/issue-68112.stderr @@ -0,0 +1,40 @@ +error: future cannot be sent between threads safely + --> $DIR/issue-68112.rs:33:5 + | +LL | fn require_send(_: impl Send) {} + | ------------ ---- required by this bound in `require_send` +... +LL | require_send(send_gen); + | ^^^^^^^^^^^^ future returned by `test1` is not `Send` + | + = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>` +note: future is not `Send` as this value is used across an yield + --> $DIR/issue-68112.rs:31:9 + | +LL | let _non_send_gen = make_non_send_generator(); + | ------------- has type `impl std::ops::Generator` +LL | yield; + | ^^^^^ yield occurs here, with `_non_send_gen` maybe used later +LL | }; + | - `_non_send_gen` is later dropped here + +error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely + --> $DIR/issue-68112.rs:52:5 + | +LL | fn require_send(_: impl Send) {} + | ------------ ---- required by this bound in `require_send` +... +LL | require_send(send_gen); + | ^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>` + = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::cell::RefCell<i32>>` + = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:38:5: 41:6 t:std::sync::Arc<std::cell::RefCell<i32>> {()}]` + = note: required because it appears within the type `impl std::ops::Generator` + = note: required because it appears within the type `impl std::ops::Generator` + = note: required because it appears within the type `{impl std::ops::Generator, ()}` + = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6 {impl std::ops::Generator, ()}]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. |
