Add test for #68112 (existing output)

This commit is contained in:
Tyler Mandry 2020-03-24 17:23:50 -07:00
parent b129b32afa
commit a40ec13262
4 changed files with 194 additions and 0 deletions

View File

@ -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() {}

View File

@ -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`.

View File

@ -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() {}

View File

@ -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`.