Skip to content

Commit adda0cd

Browse files
arora-amannull-sleeplogmosier
committed
Add tests for updated closure/generator printing
Co-authored-by: Dhruv Jauhar <dhruvjhr@gmail.com> Co-authored-by: Logan Mosier <logmosier@gmail.com>
1 parent c923da0 commit adda0cd

18 files changed

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

0 commit comments

Comments
 (0)