]> git.lizzy.rs Git - rust.git/commitdiff
Add test for #68112 (existing output)
authorTyler Mandry <tmandry@gmail.com>
Wed, 25 Mar 2020 00:23:50 +0000 (17:23 -0700)
committerTyler Mandry <tmandry@gmail.com>
Tue, 14 Apr 2020 01:48:55 +0000 (18:48 -0700)
src/test/ui/async-await/issue-68112.rs [new file with mode: 0644]
src/test/ui/async-await/issue-68112.stderr [new file with mode: 0644]
src/test/ui/generator/issue-68112.rs [new file with mode: 0644]
src/test/ui/generator/issue-68112.stderr [new file with mode: 0644]

diff --git a/src/test/ui/async-await/issue-68112.rs b/src/test/ui/async-await/issue-68112.rs
new file mode 100644 (file)
index 0000000..0d269b1
--- /dev/null
@@ -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 (file)
index 0000000..461967b
--- /dev/null
@@ -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 (file)
index 0000000..ee62cbf
--- /dev/null
@@ -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 (file)
index 0000000..b98afd4
--- /dev/null
@@ -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`.