From 65c0e68bf339bf3fdfb9f6b790f90aa30cd8dd93 Mon Sep 17 00:00:00 2001
From: Rageking8 <tomleetyt@gmail.com>
Date: Wed, 5 Oct 2022 21:54:59 +0800
Subject: [PATCH] add test for issue 82633

---
 .../closure-return-type-must-be-sized.rs      | 74 ++++++++++++++
 .../closure-return-type-must-be-sized.stderr  | 99 +++++++++++++++++++
 2 files changed, 173 insertions(+)
 create mode 100644 src/test/ui/closures/closure-return-type-must-be-sized.rs
 create mode 100644 src/test/ui/closures/closure-return-type-must-be-sized.stderr

diff --git a/src/test/ui/closures/closure-return-type-must-be-sized.rs b/src/test/ui/closures/closure-return-type-must-be-sized.rs
new file mode 100644
index 0000000000000..8cfa0291229bd
--- /dev/null
+++ b/src/test/ui/closures/closure-return-type-must-be-sized.rs
@@ -0,0 +1,74 @@
+#![feature(unboxed_closures)]
+
+trait A {
+    fn a() where Self: Sized;
+}
+
+mod a {
+    use crate::A;
+
+    pub fn foo<F: FnOnce<()>>() where F::Output: A {
+        F::Output::a()
+    }
+
+    pub fn bar<F: FnOnce() -> R, R: ?Sized>() {}
+
+    pub fn baz<F: FnOnce<()>>() where F::Output: A, F::Output: Sized {
+        F::Output::a()
+    }
+}
+
+mod b {
+    use crate::A;
+
+    pub fn foo<F: Fn<()>>() where F::Output: A {
+        F::Output::a()
+    }
+
+    pub fn bar<F: Fn() -> R, R: ?Sized>() {}
+
+    pub fn baz<F: Fn<()>>() where F::Output: A, F::Output: Sized {
+        F::Output::a()
+    }
+}
+
+mod c {
+    use crate::A;
+
+    pub fn foo<F: FnMut<()>>() where F::Output: A {
+        F::Output::a()
+    }
+
+    pub fn bar<F: FnMut() -> R, R: ?Sized>() {}
+
+    pub fn baz<F: FnMut<()>>() where F::Output: A, F::Output: Sized {
+        F::Output::a()
+    }
+}
+
+impl A for Box<dyn A> {
+    fn a() {}
+}
+
+fn main() {
+    a::foo::<fn() -> dyn A>();         //~ ERROR E0277
+    a::bar::<fn() -> dyn A, _>();      //~ ERROR E0277
+    a::baz::<fn() -> dyn A>();         //~ ERROR E0277
+    a::foo::<fn() -> Box<dyn A>>();    //  ok
+    a::bar::<fn() -> Box<dyn A>, _>(); //  ok
+    a::baz::<fn() -> Box<dyn A>>();    //  ok
+
+    b::foo::<fn() -> dyn A>();         //~ ERROR E0277
+    b::bar::<fn() -> dyn A, _>();      //~ ERROR E0277
+    b::baz::<fn() -> dyn A>();         //~ ERROR E0277
+    b::foo::<fn() -> Box<dyn A>>();    //  ok
+    b::bar::<fn() -> Box<dyn A>, _>(); //  ok
+    b::baz::<fn() -> Box<dyn A>>();    //  ok
+
+    c::foo::<fn() -> dyn A>();         //~ ERROR E0277
+    c::bar::<fn() -> dyn A, _>();      //~ ERROR E0277
+    c::baz::<fn() -> dyn A>();         //~ ERROR E0277
+    c::foo::<fn() -> Box<dyn A>>();    //  ok
+    c::bar::<fn() -> Box<dyn A>, _>(); //  ok
+    c::baz::<fn() -> Box<dyn A>>();    //  ok
+}
diff --git a/src/test/ui/closures/closure-return-type-must-be-sized.stderr b/src/test/ui/closures/closure-return-type-must-be-sized.stderr
new file mode 100644
index 0000000000000..b07425bd82501
--- /dev/null
+++ b/src/test/ui/closures/closure-return-type-must-be-sized.stderr
@@ -0,0 +1,99 @@
+error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
+  --> $DIR/closure-return-type-must-be-sized.rs:54:5
+   |
+LL |     a::foo::<fn() -> dyn A>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
+   = note: required because it appears within the type `fn() -> dyn A`
+
+error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
+  --> $DIR/closure-return-type-must-be-sized.rs:55:14
+   |
+LL |     a::bar::<fn() -> dyn A, _>();
+   |              ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
+   = note: required because it appears within the type `fn() -> dyn A`
+note: required by a bound in `a::bar`
+  --> $DIR/closure-return-type-must-be-sized.rs:14:19
+   |
+LL |     pub fn bar<F: FnOnce() -> R, R: ?Sized>() {}
+   |                   ^^^^^^^^^^^^^ required by this bound in `a::bar`
+
+error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
+  --> $DIR/closure-return-type-must-be-sized.rs:56:5
+   |
+LL |     a::baz::<fn() -> dyn A>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
+   = note: required because it appears within the type `fn() -> dyn A`
+
+error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
+  --> $DIR/closure-return-type-must-be-sized.rs:61:5
+   |
+LL |     b::foo::<fn() -> dyn A>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
+   = note: required because it appears within the type `fn() -> dyn A`
+
+error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
+  --> $DIR/closure-return-type-must-be-sized.rs:62:14
+   |
+LL |     b::bar::<fn() -> dyn A, _>();
+   |              ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
+   = note: required because it appears within the type `fn() -> dyn A`
+note: required by a bound in `b::bar`
+  --> $DIR/closure-return-type-must-be-sized.rs:28:19
+   |
+LL |     pub fn bar<F: Fn() -> R, R: ?Sized>() {}
+   |                   ^^^^^^^^^ required by this bound in `b::bar`
+
+error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
+  --> $DIR/closure-return-type-must-be-sized.rs:63:5
+   |
+LL |     b::baz::<fn() -> dyn A>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
+   = note: required because it appears within the type `fn() -> dyn A`
+
+error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
+  --> $DIR/closure-return-type-must-be-sized.rs:68:5
+   |
+LL |     c::foo::<fn() -> dyn A>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
+   = note: required because it appears within the type `fn() -> dyn A`
+
+error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
+  --> $DIR/closure-return-type-must-be-sized.rs:69:14
+   |
+LL |     c::bar::<fn() -> dyn A, _>();
+   |              ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
+   = note: required because it appears within the type `fn() -> dyn A`
+note: required by a bound in `c::bar`
+  --> $DIR/closure-return-type-must-be-sized.rs:42:19
+   |
+LL |     pub fn bar<F: FnMut() -> R, R: ?Sized>() {}
+   |                   ^^^^^^^^^^^^ required by this bound in `c::bar`
+
+error[E0277]: the size for values of type `dyn A` cannot be known at compilation time
+  --> $DIR/closure-return-type-must-be-sized.rs:70:5
+   |
+LL |     c::baz::<fn() -> dyn A>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `fn() -> dyn A`, the trait `Sized` is not implemented for `dyn A`
+   = note: required because it appears within the type `fn() -> dyn A`
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0277`.