summaryrefslogtreecommitdiffstats
path: root/src/test/ui/closure-expected-type
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/closure-expected-type
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/closure-expected-type')
-rw-r--r--src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs38
-rw-r--r--src/test/ui/closure-expected-type/expect-fn-supply-fn.rs60
-rw-r--r--src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr51
-rw-r--r--src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.rs25
-rw-r--r--src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr21
-rw-r--r--src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs19
-rw-r--r--src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs19
-rw-r--r--src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.rs19
-rw-r--r--src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr14
-rw-r--r--src/test/ui/closure-expected-type/issue-24421.rs10
10 files changed, 276 insertions, 0 deletions
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs b/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs
new file mode 100644
index 000000000..5f02e642d
--- /dev/null
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs
@@ -0,0 +1,38 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![allow(warnings)]
+
+type Different<'a, 'b> = &'a mut (&'a (), &'b ());
+type Same<'a> = Different<'a, 'a>;
+
+fn with_closure_expecting_different<F>(_: F)
+ where F: for<'a, 'b> FnOnce(Different<'a, 'b>)
+{
+}
+
+fn with_closure_expecting_different_anon<F>(_: F)
+ where F: FnOnce(Different<'_, '_>)
+{
+}
+
+fn supplying_nothing_expecting_anon() {
+ with_closure_expecting_different_anon(|x: Different| {
+ })
+}
+
+fn supplying_nothing_expecting_named() {
+ with_closure_expecting_different(|x: Different| {
+ })
+}
+
+fn supplying_underscore_expecting_anon() {
+ with_closure_expecting_different_anon(|x: Different<'_, '_>| {
+ })
+}
+
+fn supplying_underscore_expecting_named() {
+ with_closure_expecting_different(|x: Different<'_, '_>| {
+ })
+}
+
+fn main() { }
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs
new file mode 100644
index 000000000..7f1c14027
--- /dev/null
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.rs
@@ -0,0 +1,60 @@
+fn with_closure_expecting_fn_with_free_region<F>(_: F)
+where
+ F: for<'a> FnOnce(fn(&'a u32), &i32),
+{
+}
+
+fn with_closure_expecting_fn_with_bound_region<F>(_: F)
+where
+ F: FnOnce(fn(&u32), &i32),
+{
+}
+
+fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
+ // Here, the type given for `'x` "obscures" a region from the
+ // expected signature that is bound at closure level.
+ with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
+ //~^ ERROR lifetime may not live long enough
+ //~| ERROR lifetime may not live long enough
+}
+
+fn expect_free_supply_free_from_closure() {
+ // A variant on the previous test. Here, the region `'a` will be
+ // bound at the closure level, just as is expected, so no error
+ // results.
+ type Foo<'a> = fn(&'a u32);
+ with_closure_expecting_fn_with_free_region(|_x: Foo<'_>, y| {});
+}
+
+fn expect_free_supply_bound() {
+ // Here, we are given a function whose region is bound at closure level,
+ // but we expect one bound in the argument. Error results.
+ with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
+ //~^ ERROR mismatched types
+}
+
+fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) {
+ // Here, we are given a `fn(&u32)` but we expect a `fn(&'x
+ // u32)`. In principle, this could be ok, but we demand equality.
+ with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
+ //~^ ERROR mismatched types
+}
+
+fn expect_bound_supply_free_from_closure() {
+ // A variant on the previous test. Here, the region `'a` will be
+ // bound at the closure level, but we expect something bound at
+ // the argument level.
+ type Foo<'a> = fn(&'a u32);
+ with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
+ //~^ ERROR mismatched types
+ });
+}
+
+fn expect_bound_supply_bound<'x>(x: &'x u32) {
+ // No error in this case. The supplied type supplies the bound
+ // regions, and hence we are able to figure out the type of `y`
+ // from the expected type
+ with_closure_expecting_fn_with_bound_region(|x: for<'z> fn(&'z u32), y| {});
+}
+
+fn main() {}
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
new file mode 100644
index 000000000..26f47eb68
--- /dev/null
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
@@ -0,0 +1,51 @@
+error: lifetime may not live long enough
+ --> $DIR/expect-fn-supply-fn.rs:16:49
+ |
+LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
+ | -- lifetime `'x` defined here
+...
+LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
+ | ^
+ | |
+ | has type `fn(&'1 u32)`
+ | requires that `'1` must outlive `'x`
+
+error: lifetime may not live long enough
+ --> $DIR/expect-fn-supply-fn.rs:16:49
+ |
+LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
+ | -- lifetime `'x` defined here
+...
+LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
+ | ^ requires that `'x` must outlive `'static`
+
+error[E0308]: mismatched types
+ --> $DIR/expect-fn-supply-fn.rs:32:49
+ |
+LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
+ | ^ one type is more general than the other
+ |
+ = note: expected fn pointer `for<'r> fn(&'r u32)`
+ found fn pointer `fn(&u32)`
+
+error[E0308]: mismatched types
+ --> $DIR/expect-fn-supply-fn.rs:39:50
+ |
+LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
+ | ^ one type is more general than the other
+ |
+ = note: expected fn pointer `fn(&'x u32)`
+ found fn pointer `for<'r> fn(&'r u32)`
+
+error[E0308]: mismatched types
+ --> $DIR/expect-fn-supply-fn.rs:48:50
+ |
+LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
+ | ^ one type is more general than the other
+ |
+ = note: expected fn pointer `fn(&u32)`
+ found fn pointer `for<'r> fn(&'r u32)`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.rs b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.rs
new file mode 100644
index 000000000..e5ec6b271
--- /dev/null
+++ b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.rs
@@ -0,0 +1,25 @@
+fn with_closure<F, A>(_: F)
+ where F: FnOnce(A, A)
+{
+}
+
+fn a() {
+ with_closure(|x: u32, y| {
+ // We deduce type of `y` from `x`.
+ });
+}
+
+fn b() {
+ // Here we take the supplied types, resulting in an error later on.
+ with_closure(|x: u32, y: i32| {
+ //~^ ERROR type mismatch in closure arguments
+ });
+}
+
+fn c() {
+ with_closure(|x, y: i32| {
+ // We deduce type of `x` from `y`.
+ });
+}
+
+fn main() { }
diff --git a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
new file mode 100644
index 000000000..8dccf929b
--- /dev/null
+++ b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
@@ -0,0 +1,21 @@
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/expect-infer-var-appearing-twice.rs:14:5
+ |
+LL | with_closure(|x: u32, y: i32| {
+ | ^^^^^^^^^^^^ ---------------- found signature defined here
+ | |
+ | expected due to this
+ |
+ = note: expected closure signature `fn(_, _) -> _`
+ found closure signature `fn(u32, i32) -> _`
+note: required by a bound in `with_closure`
+ --> $DIR/expect-infer-var-appearing-twice.rs:2:14
+ |
+LL | fn with_closure<F, A>(_: F)
+ | ------------ required by a bound in this
+LL | where F: FnOnce(A, A)
+ | ^^^^^^^^^^^^ required by this bound in `with_closure`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0631`.
diff --git a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs
new file mode 100644
index 000000000..0ee738c2c
--- /dev/null
+++ b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs
@@ -0,0 +1,19 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+fn with_closure<F, A>(_: F)
+ where F: FnOnce(A, &u32)
+{
+}
+
+fn foo() {
+ // This version works; we infer `A` to be `u32`, and take the type
+ // of `y` to be `&u32`.
+ with_closure(|x: u32, y| {});
+}
+
+fn bar() {
+ // This version also works.
+ with_closure(|x: &u32, y| {});
+}
+
+fn main() { }
diff --git a/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs
new file mode 100644
index 000000000..15711da4b
--- /dev/null
+++ b/src/test/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs
@@ -0,0 +1,19 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+fn with_closure<F, A>(_: F)
+ where F: FnOnce(A, &u32)
+{
+}
+
+fn foo() {
+ // This version works; we infer `A` to be `u32`, and take the type
+ // of `y` to be `&u32`.
+ with_closure(|x: u32, y| {});
+}
+
+fn bar<'x>(x: &'x u32) {
+ // Same.
+ with_closure(|x: &'x u32, y| {});
+}
+
+fn main() { }
diff --git a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.rs b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.rs
new file mode 100644
index 000000000..97d7a51a7
--- /dev/null
+++ b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.rs
@@ -0,0 +1,19 @@
+fn with_closure<F, A, B>(_: F)
+ where F: FnOnce(A, B)
+{
+}
+
+fn a() {
+ // Type of `y` is unconstrained.
+ with_closure(|x: u32, y| {}); //~ ERROR E0282
+}
+
+fn b() {
+ with_closure(|x: u32, y: u32| {}); // OK
+}
+
+fn c() {
+ with_closure(|x: u32, y: u32| {}); // OK
+}
+
+fn main() { }
diff --git a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr
new file mode 100644
index 000000000..db7586bee
--- /dev/null
+++ b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr
@@ -0,0 +1,14 @@
+error[E0282]: type annotations needed
+ --> $DIR/expect-two-infer-vars-supply-ty-with-bound-region.rs:8:27
+ |
+LL | with_closure(|x: u32, y| {});
+ | ^
+ |
+help: consider giving this closure parameter an explicit type
+ |
+LL | with_closure(|x: u32, y: B| {});
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/closure-expected-type/issue-24421.rs b/src/test/ui/closure-expected-type/issue-24421.rs
new file mode 100644
index 000000000..2e104b599
--- /dev/null
+++ b/src/test/ui/closure-expected-type/issue-24421.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+fn test<F: Fn(&u64, &u64)>(f: F) {}
+
+fn main() {
+ test(|x, y | {});
+ test(|x:&u64, y:&u64| {});
+ test(|x:&u64, y | {});
+ test(|x, y:&u64| {});
+}