Skip to content

Commit a40ec13

Browse files
committed
Add test for rust-lang#68112 (existing output)
1 parent b129b32 commit a40ec13

File tree

4 files changed

+194
-0
lines changed

4 files changed

+194
-0
lines changed
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// edition:2018
2+
3+
use std::{
4+
future::Future,
5+
cell::RefCell,
6+
sync::Arc,
7+
pin::Pin,
8+
task::{Context, Poll},
9+
};
10+
11+
fn require_send(_: impl Send) {}
12+
13+
struct Ready<T>(Option<T>);
14+
impl<T> Future for Ready<T> {
15+
type Output = T;
16+
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
17+
Poll::Ready(self.0.take().unwrap())
18+
}
19+
}
20+
fn ready<T>(t: T) -> Ready<T> {
21+
Ready(Some(t))
22+
}
23+
24+
fn make_non_send_future1() -> impl Future<Output = Arc<RefCell<i32>>> {
25+
ready(Arc::new(RefCell::new(0)))
26+
}
27+
28+
fn test1() {
29+
let send_fut = async {
30+
let non_send_fut = make_non_send_future1();
31+
let _ = non_send_fut.await;
32+
ready(0).await;
33+
};
34+
require_send(send_fut);
35+
//~^ ERROR future cannot be sent between threads
36+
}
37+
38+
async fn ready2<T>(t: T) -> T { t }
39+
fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
40+
ready2(Arc::new(RefCell::new(0)))
41+
}
42+
43+
fn test2() {
44+
let send_fut = async {
45+
let non_send_fut = make_non_send_future2();
46+
let _ = non_send_fut.await;
47+
ready(0).await;
48+
};
49+
require_send(send_fut);
50+
//~^ ERROR `std::cell::RefCell<i32>` cannot be shared between threads safely
51+
}
52+
53+
fn main() {}
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
error: future cannot be sent between threads safely
2+
--> $DIR/issue-68112.rs:34:5
3+
|
4+
LL | fn require_send(_: impl Send) {}
5+
| ------------ ---- required by this bound in `require_send`
6+
...
7+
LL | require_send(send_fut);
8+
| ^^^^^^^^^^^^ future returned by `test1` is not `Send`
9+
|
10+
= help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
11+
note: future is not `Send` as this value is used across an await
12+
--> $DIR/issue-68112.rs:32:9
13+
|
14+
LL | let non_send_fut = make_non_send_future1();
15+
| ------------ has type `impl std::future::Future`
16+
LL | let _ = non_send_fut.await;
17+
LL | ready(0).await;
18+
| ^^^^^^^^ await occurs here, with `non_send_fut` maybe used later
19+
LL | };
20+
| - `non_send_fut` is later dropped here
21+
22+
error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
23+
--> $DIR/issue-68112.rs:49:5
24+
|
25+
LL | fn require_send(_: impl Send) {}
26+
| ------------ ---- required by this bound in `require_send`
27+
...
28+
LL | require_send(send_fut);
29+
| ^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
30+
|
31+
= help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
32+
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::cell::RefCell<i32>>`
33+
= 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>> {}]`
34+
= 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>> {}]>`
35+
= note: required because it appears within the type `impl std::future::Future`
36+
= note: required because it appears within the type `impl std::future::Future`
37+
= note: required because it appears within the type `impl std::future::Future`
38+
= note: required because it appears within the type `{std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}`
39+
= 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>}]`
40+
= 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>}]>`
41+
= note: required because it appears within the type `impl std::future::Future`
42+
43+
error: aborting due to 2 previous errors
44+
45+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/generator/issue-68112.rs

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#![feature(generators, generator_trait)]
2+
3+
use std::{
4+
cell::RefCell,
5+
sync::Arc,
6+
pin::Pin,
7+
ops::{Generator, GeneratorState},
8+
};
9+
10+
pub struct Ready<T>(Option<T>);
11+
impl<T> Generator<()> for Ready<T> {
12+
type Return = T;
13+
type Yield = ();
14+
fn resume(mut self: Pin<&mut Self>, _args: ()) -> GeneratorState<(), T> {
15+
GeneratorState::Complete(self.0.take().unwrap())
16+
}
17+
}
18+
pub fn make_gen1<T>(t: T) -> Ready<T> {
19+
Ready(Some(t))
20+
}
21+
22+
fn require_send(_: impl Send) {}
23+
24+
fn make_non_send_generator() -> impl Generator<Return = Arc<RefCell<i32>>> {
25+
make_gen1(Arc::new(RefCell::new(0)))
26+
}
27+
28+
fn test1() {
29+
let send_gen = || {
30+
let _non_send_gen = make_non_send_generator();
31+
yield;
32+
};
33+
require_send(send_gen);
34+
//~^ ERROR future cannot be sent between threads
35+
}
36+
37+
pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
38+
|| {
39+
yield;
40+
t
41+
}
42+
}
43+
fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
44+
make_gen2(Arc::new(RefCell::new(0)))
45+
}
46+
47+
fn test2() {
48+
let send_gen = || {
49+
let _non_send_gen = make_non_send_generator2();
50+
yield;
51+
};
52+
require_send(send_gen);
53+
//~^ ERROR `std::cell::RefCell<i32>` cannot be shared between threads safely
54+
}
55+
56+
fn main() {}
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
error: future cannot be sent between threads safely
2+
--> $DIR/issue-68112.rs:33:5
3+
|
4+
LL | fn require_send(_: impl Send) {}
5+
| ------------ ---- required by this bound in `require_send`
6+
...
7+
LL | require_send(send_gen);
8+
| ^^^^^^^^^^^^ future returned by `test1` is not `Send`
9+
|
10+
= help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
11+
note: future is not `Send` as this value is used across an yield
12+
--> $DIR/issue-68112.rs:31:9
13+
|
14+
LL | let _non_send_gen = make_non_send_generator();
15+
| ------------- has type `impl std::ops::Generator`
16+
LL | yield;
17+
| ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
18+
LL | };
19+
| - `_non_send_gen` is later dropped here
20+
21+
error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
22+
--> $DIR/issue-68112.rs:52:5
23+
|
24+
LL | fn require_send(_: impl Send) {}
25+
| ------------ ---- required by this bound in `require_send`
26+
...
27+
LL | require_send(send_gen);
28+
| ^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
29+
|
30+
= help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
31+
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::cell::RefCell<i32>>`
32+
= 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>> {()}]`
33+
= note: required because it appears within the type `impl std::ops::Generator`
34+
= note: required because it appears within the type `impl std::ops::Generator`
35+
= note: required because it appears within the type `{impl std::ops::Generator, ()}`
36+
= note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6 {impl std::ops::Generator, ()}]`
37+
38+
error: aborting due to 2 previous errors
39+
40+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)