Skip to content

Commit 343ba38

Browse files
arora-amannull-sleeplogmosier
committed
Add tests for updated closure/generator printing
Co-authored-by: Dhruv Jauhar <[email protected]> Co-authored-by: Logan Mosier <[email protected]>
1 parent 381d4ac commit 343ba38

22 files changed

+571
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
fn to_fn_once<F: FnOnce()>(f: F) -> F {
2+
f
3+
}
4+
5+
fn f<T: std::fmt::Display>(y: T) {
6+
struct Foo<U: std::fmt::Display> {
7+
x: U,
8+
};
9+
10+
let foo = Foo { x: "x" };
11+
12+
let c = to_fn_once(move || {
13+
println!("{} {}", foo.x, y);
14+
});
15+
16+
c();
17+
c();
18+
//~^ ERROR use of moved value
19+
}
20+
21+
fn main() {
22+
f("S");
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0382]: use of moved value: `c`
2+
--> $DIR/closure-print-generic-1.rs:17:5
3+
|
4+
LL | let c = to_fn_once(move || {
5+
| - move occurs because `c` has type `[closure@$DIR/closure-print-generic-1.rs:12:24: 14:6]`, which does not implement the `Copy` trait
6+
...
7+
LL | c();
8+
| --- `c` moved due to this call
9+
LL | c();
10+
| ^ value used here after move
11+
|
12+
note: this value implements `FnOnce`, which causes it to be moved when called
13+
--> $DIR/closure-print-generic-1.rs:16:5
14+
|
15+
LL | c();
16+
| ^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0382`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// compile-flags: -Ztrim-diagnostic-paths=off -Zverbose
2+
3+
mod mod1 {
4+
pub fn f<T: std::fmt::Display>(t: T)
5+
{
6+
let x = 20;
7+
8+
let c = || println!("{} {}", t, x);
9+
let c1 : () = c;
10+
//~^ ERROR mismatched types
11+
}
12+
}
13+
14+
fn main() {
15+
mod1::f(5i32);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/closure-print-generic-trim-off-verbose.rs:9:23
3+
|
4+
LL | let c = || println!("{} {}", t, x);
5+
| -------------------------- the found closure
6+
LL | let c1 : () = c;
7+
| -- ^ expected `()`, found closure
8+
| |
9+
| expected due to this
10+
|
11+
= note: expected unit type `()`
12+
found closure `[mod1::f<T>::{{closure}}#0 closure_substs=(unavailable)]`
13+
help: use parentheses to call this closure
14+
|
15+
LL | let c1 : () = c();
16+
| ^^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// compile-flags: -Ztrim-diagnostic-paths=off
2+
3+
mod mod1 {
4+
pub fn f<T: std::fmt::Display>(t: T)
5+
{
6+
let x = 20;
7+
8+
let c = || println!("{} {}", t, x);
9+
let c1 : () = c;
10+
//~^ ERROR mismatched types
11+
}
12+
}
13+
14+
fn main() {
15+
mod1::f(5i32);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/closure-print-generic-trim-off.rs:9:23
3+
|
4+
LL | let c = || println!("{} {}", t, x);
5+
| -------------------------- the found closure
6+
LL | let c1 : () = c;
7+
| -- ^ expected `()`, found closure
8+
| |
9+
| expected due to this
10+
|
11+
= note: expected unit type `()`
12+
found closure `[closure@$DIR/closure-print-generic-trim-off.rs:8:17: 8:43]`
13+
help: use parentheses to call this closure
14+
|
15+
LL | let c1 : () = c();
16+
| ^^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// compile-flags: -Zverbose
2+
3+
fn to_fn_once<F:FnOnce()>(f: F) -> F { f }
4+
5+
fn f<T: std::fmt::Display>(y: T) {
6+
struct Foo<U: std::fmt::Display> {
7+
x: U
8+
};
9+
10+
let foo = Foo{ x: "x" };
11+
12+
let c = to_fn_once(move|| {
13+
println!("{} {}", foo.x, y);
14+
});
15+
16+
c();
17+
c();
18+
//~^ ERROR use of moved value
19+
}
20+
21+
22+
fn main() {
23+
f("S");
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0382]: use of moved value: `c`
2+
--> $DIR/closure-print-generic-verbose-1.rs:17:5
3+
|
4+
LL | let c = to_fn_once(move|| {
5+
| - move occurs because `c` has type `[f<T>::{{closure}}#0 closure_kind_ty=i32 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvars_ty=(Foo<&'_#10r str>, T)]`, which does not implement the `Copy` trait
6+
...
7+
LL | c();
8+
| --- `c` moved due to this call
9+
LL | c();
10+
| ^ value used here after move
11+
|
12+
note: this value implements `FnOnce`, which causes it to be moved when called
13+
--> $DIR/closure-print-generic-verbose-1.rs:16:5
14+
|
15+
LL | c();
16+
| ^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0382`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// compile-flags: -Zverbose
2+
3+
mod mod1 {
4+
pub fn f<T: std::fmt::Display>(t: T)
5+
{
6+
let x = 20;
7+
8+
let c = || println!("{} {}", t, x);
9+
let c1 : () = c;
10+
//~^ ERROR mismatched types
11+
}
12+
}
13+
14+
fn main() {
15+
mod1::f(5i32);
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/closure-print-generic-verbose.rs:9:23
3+
|
4+
LL | let c = || println!("{} {}", t, x);
5+
| -------------------------- the found closure
6+
LL | let c1 : () = c;
7+
| -- ^ expected `()`, found closure
8+
| |
9+
| expected due to this
10+
|
11+
= note: expected unit type `()`
12+
found closure `[f<T>::{{closure}}#0 closure_substs=(unavailable)]`
13+
help: use parentheses to call this closure
14+
|
15+
LL | let c1 : () = c();
16+
| ^^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
mod mod1 {
2+
pub fn f<T: std::fmt::Display>(t: T) {
3+
let x = 20;
4+
5+
let c = || println!("{} {}", t, x);
6+
let c1: () = c;
7+
//~^ ERROR mismatched types
8+
}
9+
}
10+
11+
fn main() {
12+
mod1::f(5i32);
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/closure-print-generic.rs:6:22
3+
|
4+
LL | let c = || println!("{} {}", t, x);
5+
| -------------------------- the found closure
6+
LL | let c1: () = c;
7+
| -- ^ expected `()`, found closure
8+
| |
9+
| expected due to this
10+
|
11+
= note: expected unit type `()`
12+
found closure `[closure@$DIR/closure-print-generic.rs:5:17: 5:43]`
13+
help: use parentheses to call this closure
14+
|
15+
LL | let c1: () = c();
16+
| ^^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// compile-flags: -Zverbose
2+
3+
// Same as closure-coerce-fn-1.rs
4+
5+
// Ensure that capturing closures are never coerced to fns
6+
// Especially interesting as non-capturing closures can be.
7+
8+
fn main() {
9+
let mut a = 0u8;
10+
let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
11+
//~^ ERROR mismatched types
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/closure-print-verbose.rs:10:29
3+
|
4+
LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
5+
| ------------ ^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found closure
6+
| |
7+
| expected due to this
8+
|
9+
= note: expected fn pointer `fn(u8) -> u8`
10+
found closure `[main::{{closure}}#0 closure_substs=(unavailable)]`
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Same as: src/test/ui/generator/issue-68112.stderr
2+
3+
#![feature(generators, generator_trait)]
4+
5+
use std::{
6+
cell::RefCell,
7+
sync::Arc,
8+
pin::Pin,
9+
ops::{Generator, GeneratorState},
10+
};
11+
12+
pub struct Ready<T>(Option<T>);
13+
impl<T> Generator<()> for Ready<T> {
14+
type Return = T;
15+
type Yield = ();
16+
fn resume(mut self: Pin<&mut Self>, _args: ()) -> GeneratorState<(), T> {
17+
GeneratorState::Complete(self.0.take().unwrap())
18+
}
19+
}
20+
pub fn make_gen1<T>(t: T) -> Ready<T> {
21+
Ready(Some(t))
22+
}
23+
24+
fn require_send(_: impl Send) {}
25+
26+
fn make_non_send_generator() -> impl Generator<Return = Arc<RefCell<i32>>> {
27+
make_gen1(Arc::new(RefCell::new(0)))
28+
}
29+
30+
fn test1() {
31+
let send_gen = || {
32+
let _non_send_gen = make_non_send_generator();
33+
yield;
34+
};
35+
require_send(send_gen);
36+
//~^ ERROR generator cannot be sent between threads
37+
}
38+
39+
pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
40+
|| {
41+
yield;
42+
t
43+
}
44+
}
45+
fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
46+
make_gen2(Arc::new(RefCell::new(0)))
47+
}
48+
49+
fn test2() {
50+
let send_gen = || {
51+
let _non_send_gen = make_non_send_generator2();
52+
yield;
53+
};
54+
require_send(send_gen);
55+
//~^ ERROR `RefCell<i32>` cannot be shared between threads safely
56+
}
57+
58+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
error: generator cannot be sent between threads safely
2+
--> $DIR/generator-print-1.rs:35: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+
| ^^^^^^^^^^^^ generator is not `Send`
9+
|
10+
= help: the trait `Sync` is not implemented for `RefCell<i32>`
11+
note: generator is not `Send` as this value is used across a yield
12+
--> $DIR/generator-print-1.rs:33:9
13+
|
14+
LL | let _non_send_gen = make_non_send_generator();
15+
| ------------- has type `impl Generator` which is not `Send`
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]: `RefCell<i32>` cannot be shared between threads safely
22+
--> $DIR/generator-print-1.rs:54: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+
| ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
29+
|
30+
= help: the trait `Sync` is not implemented for `RefCell<i32>`
31+
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
32+
= note: required because it appears within the type `[generator@$DIR/generator-print-1.rs:40:5: 43:6 {()}]`
33+
= note: required because it appears within the type `impl Generator`
34+
= note: required because it appears within the type `impl Generator`
35+
= note: required because it appears within the type `{impl Generator, ()}`
36+
= note: required because it appears within the type `[generator@$DIR/generator-print-1.rs:50:20: 53:6 {impl Generator, ()}]`
37+
38+
error: aborting due to 2 previous errors
39+
40+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Same as test/ui/generator/not-send-sync.rs
2+
3+
#![feature(generators)]
4+
5+
use std::cell::Cell;
6+
7+
fn main() {
8+
fn assert_sync<T: Sync>(_: T) {}
9+
fn assert_send<T: Send>(_: T) {}
10+
11+
assert_sync(|| {
12+
//~^ ERROR: generator cannot be shared between threads safely
13+
let a = Cell::new(2);
14+
yield;
15+
});
16+
17+
let a = Cell::new(2);
18+
assert_send(|| {
19+
//~^ ERROR: E0277
20+
drop(&a);
21+
yield;
22+
});
23+
}

0 commit comments

Comments
 (0)