diff --git a/src/test/ui/closures/print/closure-print-generic-1.rs b/src/test/ui/closures/print/closure-print-generic-1.rs new file mode 100644 index 0000000000000..504b4adbeb9bc --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-1.rs @@ -0,0 +1,23 @@ +fn to_fn_once(f: F) -> F { + f +} + +fn f(y: T) { + struct Foo { + x: U, + }; + + let foo = Foo { x: "x" }; + + let c = to_fn_once(move || { + println!("{} {}", foo.x, y); + }); + + c(); + c(); + //~^ ERROR use of moved value +} + +fn main() { + f("S"); +} diff --git a/src/test/ui/closures/print/closure-print-generic-1.stderr b/src/test/ui/closures/print/closure-print-generic-1.stderr new file mode 100644 index 0000000000000..43a12f675f562 --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-1.stderr @@ -0,0 +1,20 @@ +error[E0382]: use of moved value: `c` + --> $DIR/closure-print-generic-1.rs:17:5 + | +LL | let c = to_fn_once(move || { + | - move occurs because `c` has type `[closure@$DIR/closure-print-generic-1.rs:12:24: 14:6]`, which does not implement the `Copy` trait +... +LL | c(); + | --- `c` moved due to this call +LL | c(); + | ^ value used here after move + | +note: this value implements `FnOnce`, which causes it to be moved when called + --> $DIR/closure-print-generic-1.rs:16:5 + | +LL | c(); + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/closures/print/closure-print-generic-trim-off-verbose.rs b/src/test/ui/closures/print/closure-print-generic-trim-off-verbose.rs new file mode 100644 index 0000000000000..07bf8fe4c0076 --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-trim-off-verbose.rs @@ -0,0 +1,16 @@ +// compile-flags: -Ztrim-diagnostic-paths=off -Zverbose + +mod mod1 { + pub fn f(t: T) + { + let x = 20; + + let c = || println!("{} {}", t, x); + let c1 : () = c; + //~^ ERROR mismatched types + } +} + +fn main() { + mod1::f(5i32); +} diff --git a/src/test/ui/closures/print/closure-print-generic-trim-off-verbose.stderr b/src/test/ui/closures/print/closure-print-generic-trim-off-verbose.stderr new file mode 100644 index 0000000000000..9e35512f1fe9f --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-trim-off-verbose.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/closure-print-generic-trim-off-verbose.rs:9:23 + | +LL | let c = || println!("{} {}", t, x); + | -------------------------- the found closure +LL | let c1 : () = c; + | -- ^ expected `()`, found closure + | | + | expected due to this + | + = note: expected unit type `()` + found closure `[mod1::f::{{closure}}#0 closure_substs=(unavailable)]` +help: use parentheses to call this closure + | +LL | let c1 : () = c(); + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/closures/print/closure-print-generic-trim-off.rs b/src/test/ui/closures/print/closure-print-generic-trim-off.rs new file mode 100644 index 0000000000000..a39335db2851b --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-trim-off.rs @@ -0,0 +1,16 @@ +// compile-flags: -Ztrim-diagnostic-paths=off + +mod mod1 { + pub fn f(t: T) + { + let x = 20; + + let c = || println!("{} {}", t, x); + let c1 : () = c; + //~^ ERROR mismatched types + } +} + +fn main() { + mod1::f(5i32); +} diff --git a/src/test/ui/closures/print/closure-print-generic-trim-off.stderr b/src/test/ui/closures/print/closure-print-generic-trim-off.stderr new file mode 100644 index 0000000000000..aa2f103b2c647 --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-trim-off.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/closure-print-generic-trim-off.rs:9:23 + | +LL | let c = || println!("{} {}", t, x); + | -------------------------- the found closure +LL | let c1 : () = c; + | -- ^ expected `()`, found closure + | | + | expected due to this + | + = note: expected unit type `()` + found closure `[closure@$DIR/closure-print-generic-trim-off.rs:8:17: 8:43]` +help: use parentheses to call this closure + | +LL | let c1 : () = c(); + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/closures/print/closure-print-generic-verbose-1.rs b/src/test/ui/closures/print/closure-print-generic-verbose-1.rs new file mode 100644 index 0000000000000..67d37f1c59b40 --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-verbose-1.rs @@ -0,0 +1,24 @@ +// compile-flags: -Zverbose + +fn to_fn_once(f: F) -> F { f } + +fn f(y: T) { + struct Foo { + x: U + }; + + let foo = Foo{ x: "x" }; + + let c = to_fn_once(move|| { + println!("{} {}", foo.x, y); + }); + + c(); + c(); + //~^ ERROR use of moved value +} + + +fn main() { + f("S"); +} diff --git a/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr b/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr new file mode 100644 index 0000000000000..f71cf3453c6cf --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-verbose-1.stderr @@ -0,0 +1,20 @@ +error[E0382]: use of moved value: `c` + --> $DIR/closure-print-generic-verbose-1.rs:17:5 + | +LL | let c = to_fn_once(move|| { + | - move occurs because `c` has type `[f::{{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 +... +LL | c(); + | --- `c` moved due to this call +LL | c(); + | ^ value used here after move + | +note: this value implements `FnOnce`, which causes it to be moved when called + --> $DIR/closure-print-generic-verbose-1.rs:16:5 + | +LL | c(); + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/closures/print/closure-print-generic-verbose.rs b/src/test/ui/closures/print/closure-print-generic-verbose.rs new file mode 100644 index 0000000000000..f460fedffb7fb --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-verbose.rs @@ -0,0 +1,16 @@ +// compile-flags: -Zverbose + +mod mod1 { + pub fn f(t: T) + { + let x = 20; + + let c = || println!("{} {}", t, x); + let c1 : () = c; + //~^ ERROR mismatched types + } +} + +fn main() { + mod1::f(5i32); +} diff --git a/src/test/ui/closures/print/closure-print-generic-verbose.stderr b/src/test/ui/closures/print/closure-print-generic-verbose.stderr new file mode 100644 index 0000000000000..041ee83d50356 --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic-verbose.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/closure-print-generic-verbose.rs:9:23 + | +LL | let c = || println!("{} {}", t, x); + | -------------------------- the found closure +LL | let c1 : () = c; + | -- ^ expected `()`, found closure + | | + | expected due to this + | + = note: expected unit type `()` + found closure `[f::{{closure}}#0 closure_substs=(unavailable)]` +help: use parentheses to call this closure + | +LL | let c1 : () = c(); + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/closures/print/closure-print-generic.rs b/src/test/ui/closures/print/closure-print-generic.rs new file mode 100644 index 0000000000000..3f77fd26b1772 --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic.rs @@ -0,0 +1,13 @@ +mod mod1 { + pub fn f(t: T) { + let x = 20; + + let c = || println!("{} {}", t, x); + let c1: () = c; + //~^ ERROR mismatched types + } +} + +fn main() { + mod1::f(5i32); +} diff --git a/src/test/ui/closures/print/closure-print-generic.stderr b/src/test/ui/closures/print/closure-print-generic.stderr new file mode 100644 index 0000000000000..8fbd854e66e04 --- /dev/null +++ b/src/test/ui/closures/print/closure-print-generic.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/closure-print-generic.rs:6:22 + | +LL | let c = || println!("{} {}", t, x); + | -------------------------- the found closure +LL | let c1: () = c; + | -- ^ expected `()`, found closure + | | + | expected due to this + | + = note: expected unit type `()` + found closure `[closure@$DIR/closure-print-generic.rs:5:17: 5:43]` +help: use parentheses to call this closure + | +LL | let c1: () = c(); + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/closures/print/closure-print-verbose.rs b/src/test/ui/closures/print/closure-print-verbose.rs new file mode 100644 index 0000000000000..4b0438a91ed2e --- /dev/null +++ b/src/test/ui/closures/print/closure-print-verbose.rs @@ -0,0 +1,12 @@ +// compile-flags: -Zverbose + +// Same as closure-coerce-fn-1.rs + +// Ensure that capturing closures are never coerced to fns +// Especially interesting as non-capturing closures can be. + +fn main() { + let mut a = 0u8; + let foo: fn(u8) -> u8 = |v: u8| { a += v; a }; + //~^ ERROR mismatched types +} diff --git a/src/test/ui/closures/print/closure-print-verbose.stderr b/src/test/ui/closures/print/closure-print-verbose.stderr new file mode 100644 index 0000000000000..45610947599b7 --- /dev/null +++ b/src/test/ui/closures/print/closure-print-verbose.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/closure-print-verbose.rs:10:29 + | +LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a }; + | ------------ ^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found closure + | | + | expected due to this + | + = note: expected fn pointer `fn(u8) -> u8` + found closure `[main::{{closure}}#0 closure_substs=(unavailable)]` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/generator/print/generator-print-1.rs b/src/test/ui/generator/print/generator-print-1.rs new file mode 100644 index 0000000000000..f424caf20451b --- /dev/null +++ b/src/test/ui/generator/print/generator-print-1.rs @@ -0,0 +1,58 @@ +// Same as: src/test/ui/generator/issue-68112.stderr + +#![feature(generators, generator_trait)] + +use std::{ + cell::RefCell, + sync::Arc, + pin::Pin, + ops::{Generator, GeneratorState}, +}; + +pub struct Ready(Option); +impl Generator<()> for Ready { + 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) -> Ready { + Ready(Some(t)) +} + +fn require_send(_: impl Send) {} + +fn make_non_send_generator() -> impl Generator>> { + 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 generator cannot be sent between threads +} + +pub fn make_gen2(t: T) -> impl Generator { + || { + yield; + t + } +} +fn make_non_send_generator2() -> impl Generator>> { + 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 `RefCell` cannot be shared between threads safely +} + +fn main() {} diff --git a/src/test/ui/generator/print/generator-print-1.stderr b/src/test/ui/generator/print/generator-print-1.stderr new file mode 100644 index 0000000000000..873fe75416a59 --- /dev/null +++ b/src/test/ui/generator/print/generator-print-1.stderr @@ -0,0 +1,40 @@ +error: generator cannot be sent between threads safely + --> $DIR/generator-print-1.rs:35:5 + | +LL | fn require_send(_: impl Send) {} + | ---- required by this bound in `require_send` +... +LL | require_send(send_gen); + | ^^^^^^^^^^^^ generator is not `Send` + | + = help: the trait `Sync` is not implemented for `RefCell` +note: generator is not `Send` as this value is used across a yield + --> $DIR/generator-print-1.rs:33:9 + | +LL | let _non_send_gen = make_non_send_generator(); + | ------------- has type `impl Generator` which is not `Send` +LL | yield; + | ^^^^^ yield occurs here, with `_non_send_gen` maybe used later +LL | }; + | - `_non_send_gen` is later dropped here + +error[E0277]: `RefCell` cannot be shared between threads safely + --> $DIR/generator-print-1.rs:54:5 + | +LL | fn require_send(_: impl Send) {} + | ---- required by this bound in `require_send` +... +LL | require_send(send_gen); + | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `RefCell` + = note: required because of the requirements on the impl of `Send` for `Arc>` + = note: required because it appears within the type `[generator@$DIR/generator-print-1.rs:40:5: 43:6 {()}]` + = note: required because it appears within the type `impl Generator` + = note: required because it appears within the type `impl Generator` + = note: required because it appears within the type `{impl Generator, ()}` + = note: required because it appears within the type `[generator@$DIR/generator-print-1.rs:50:20: 53:6 {impl Generator, ()}]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/print/generator-print-2.rs b/src/test/ui/generator/print/generator-print-2.rs new file mode 100644 index 0000000000000..7c48324269013 --- /dev/null +++ b/src/test/ui/generator/print/generator-print-2.rs @@ -0,0 +1,23 @@ +// Same as test/ui/generator/not-send-sync.rs + +#![feature(generators)] + +use std::cell::Cell; + +fn main() { + fn assert_sync(_: T) {} + fn assert_send(_: T) {} + + assert_sync(|| { + //~^ ERROR: generator cannot be shared between threads safely + let a = Cell::new(2); + yield; + }); + + let a = Cell::new(2); + assert_send(|| { + //~^ ERROR: E0277 + drop(&a); + yield; + }); +} diff --git a/src/test/ui/generator/print/generator-print-2.stderr b/src/test/ui/generator/print/generator-print-2.stderr new file mode 100644 index 0000000000000..59fc2dbed20fa --- /dev/null +++ b/src/test/ui/generator/print/generator-print-2.stderr @@ -0,0 +1,36 @@ +error[E0277]: `Cell` cannot be shared between threads safely + --> $DIR/generator-print-2.rs:18:5 + | +LL | fn assert_send(_: T) {} + | ---- required by this bound in `assert_send` +... +LL | assert_send(|| { + | ^^^^^^^^^^^ `Cell` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `Cell` + = note: required because of the requirements on the impl of `Send` for `&Cell` + = note: required because it appears within the type `[generator@$DIR/generator-print-2.rs:18:17: 22:6 _]` + +error: generator cannot be shared between threads safely + --> $DIR/generator-print-2.rs:11:5 + | +LL | fn assert_sync(_: T) {} + | ---- required by this bound in `assert_sync` +... +LL | assert_sync(|| { + | ^^^^^^^^^^^ generator is not `Sync` + | + = help: within `[generator@$DIR/generator-print-2.rs:11:17: 15:6 {Cell, ()}]`, the trait `Sync` is not implemented for `Cell` +note: generator is not `Sync` as this value is used across a yield + --> $DIR/generator-print-2.rs:14:9 + | +LL | let a = Cell::new(2); + | - has type `Cell` which is not `Sync` +LL | yield; + | ^^^^^ yield occurs here, with `a` maybe used later +LL | }); + | - `a` is later dropped here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/print/generator-print-verbose-1.rs b/src/test/ui/generator/print/generator-print-verbose-1.rs new file mode 100644 index 0000000000000..fe0687722b0b9 --- /dev/null +++ b/src/test/ui/generator/print/generator-print-verbose-1.rs @@ -0,0 +1,60 @@ +// compile-flags: -Zverbose + +// Same as: src/test/ui/generator/issue-68112.stderr + +#![feature(generators, generator_trait)] + +use std::{ + cell::RefCell, + sync::Arc, + pin::Pin, + ops::{Generator, GeneratorState}, +}; + +pub struct Ready(Option); +impl Generator<()> for Ready { + 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) -> Ready { + Ready(Some(t)) +} + +fn require_send(_: impl Send) {} + +fn make_non_send_generator() -> impl Generator>> { + 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 generator cannot be sent between threads +} + +pub fn make_gen2(t: T) -> impl Generator { + || { + yield; + t + } +} +fn make_non_send_generator2() -> impl Generator>> { + 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 `RefCell` cannot be shared between threads safely +} + +fn main() {} diff --git a/src/test/ui/generator/print/generator-print-verbose-1.stderr b/src/test/ui/generator/print/generator-print-verbose-1.stderr new file mode 100644 index 0000000000000..e48a77f923add --- /dev/null +++ b/src/test/ui/generator/print/generator-print-verbose-1.stderr @@ -0,0 +1,40 @@ +error: generator cannot be sent between threads safely + --> $DIR/generator-print-verbose-1.rs:37:5 + | +LL | fn require_send(_: impl Send) {} + | ---- required by this bound in `require_send` +... +LL | require_send(send_gen); + | ^^^^^^^^^^^^ generator is not `Send` + | + = help: the trait `Sync` is not implemented for `RefCell` +note: generator is not `Send` as this value is used across a yield + --> $DIR/generator-print-verbose-1.rs:35:9 + | +LL | let _non_send_gen = make_non_send_generator(); + | ------------- has type `Opaque(DefId(0:24 ~ generator_print_verbose_1[317d]::make_non_send_generator[0]::{{opaque}}[0]), [])` which is not `Send` +LL | yield; + | ^^^^^ yield occurs here, with `_non_send_gen` maybe used later +LL | }; + | - `_non_send_gen` is later dropped here + +error[E0277]: `RefCell` cannot be shared between threads safely + --> $DIR/generator-print-verbose-1.rs:56:5 + | +LL | fn require_send(_: impl Send) {} + | ---- required by this bound in `require_send` +... +LL | require_send(send_gen); + | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `RefCell` + = note: required because of the requirements on the impl of `Send` for `Arc>` + = note: required because it appears within the type `[make_gen2>>::{{closure}}#0 upvars_ty=(unavailable) {()}]` + = note: required because it appears within the type `Opaque(DefId(0:29 ~ generator_print_verbose_1[317d]::make_gen2[0]::{{opaque}}[0]), [std::sync::Arc>])` + = note: required because it appears within the type `Opaque(DefId(0:32 ~ generator_print_verbose_1[317d]::make_non_send_generator2[0]::{{opaque}}[0]), [])` + = note: required because it appears within the type `{Opaque(DefId(0:32 ~ generator_print_verbose_1[317d]::make_non_send_generator2[0]::{{opaque}}[0]), []), ()}` + = note: required because it appears within the type `[test2::{{closure}}#0 upvars_ty=(unavailable) {Opaque(DefId(0:32 ~ generator_print_verbose_1[317d]::make_non_send_generator2[0]::{{opaque}}[0]), []), ()}]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/print/generator-print-verbose-2.rs b/src/test/ui/generator/print/generator-print-verbose-2.rs new file mode 100644 index 0000000000000..d914719cb36bb --- /dev/null +++ b/src/test/ui/generator/print/generator-print-verbose-2.rs @@ -0,0 +1,24 @@ +// compile-flags: -Zverbose + +// Same as test/ui/generator/not-send-sync.rs +#![feature(generators)] + +use std::cell::Cell; + +fn main() { + fn assert_sync(_: T) {} + fn assert_send(_: T) {} + + assert_sync(|| { + //~^ ERROR: generator cannot be shared between threads safely + let a = Cell::new(2); + yield; + }); + + let a = Cell::new(2); + assert_send(|| { + //~^ ERROR: E0277 + drop(&a); + yield; + }); +} diff --git a/src/test/ui/generator/print/generator-print-verbose-2.stderr b/src/test/ui/generator/print/generator-print-verbose-2.stderr new file mode 100644 index 0000000000000..ba2abcaec43d2 --- /dev/null +++ b/src/test/ui/generator/print/generator-print-verbose-2.stderr @@ -0,0 +1,36 @@ +error[E0277]: `Cell` cannot be shared between threads safely + --> $DIR/generator-print-verbose-2.rs:19:5 + | +LL | fn assert_send(_: T) {} + | ---- required by this bound in `assert_send` +... +LL | assert_send(|| { + | ^^^^^^^^^^^ `Cell` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `Cell` + = note: required because of the requirements on the impl of `Send` for `&'_#3r Cell` + = note: required because it appears within the type `[main::{{closure}}#1 upvars_ty=(unavailable) _#16t]` + +error: generator cannot be shared between threads safely + --> $DIR/generator-print-verbose-2.rs:12:5 + | +LL | fn assert_sync(_: T) {} + | ---- required by this bound in `assert_sync` +... +LL | assert_sync(|| { + | ^^^^^^^^^^^ generator is not `Sync` + | + = help: within `[main::{{closure}}#0 upvars_ty=(unavailable) {Cell, ()}]`, the trait `Sync` is not implemented for `Cell` +note: generator is not `Sync` as this value is used across a yield + --> $DIR/generator-print-verbose-2.rs:15:9 + | +LL | let a = Cell::new(2); + | - has type `Cell` which is not `Sync` +LL | yield; + | ^^^^^ yield occurs here, with `a` maybe used later +LL | }); + | - `a` is later dropped here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.