summaryrefslogtreecommitdiffstats
path: root/tests/ui/functions-closures/closure-expected-type
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/functions-closures/closure-expected-type
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/functions-closures/closure-expected-type')
-rw-r--r--tests/ui/functions-closures/closure-expected-type/README.md8
-rw-r--r--tests/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs19
-rw-r--r--tests/ui/functions-closures/closure-expected-type/issue-38714.rs19
-rw-r--r--tests/ui/functions-closures/closure-expected-type/supply-just-return-type.rs26
-rw-r--r--tests/ui/functions-closures/closure-expected-type/supply-nothing.rs11
5 files changed, 83 insertions, 0 deletions
diff --git a/tests/ui/functions-closures/closure-expected-type/README.md b/tests/ui/functions-closures/closure-expected-type/README.md
new file mode 100644
index 000000000..0b749040a
--- /dev/null
+++ b/tests/ui/functions-closures/closure-expected-type/README.md
@@ -0,0 +1,8 @@
+Some tests targeted at how we deduce the types of closure arguments.
+This process is a result of some heuristics aimed at combining the
+*expected type* we have with the *actual types* that we get from
+inputs. This investigation was kicked off by #38714, which revealed
+some pretty deep flaws in the ad-hoc way that we were doing things
+before.
+
+See also `tests/ui/closure-expected-type`.
diff --git a/tests/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs b/tests/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs
new file mode 100644
index 000000000..6d5a9876c
--- /dev/null
+++ b/tests/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs
@@ -0,0 +1,19 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+fn with_closure<A, F>(_: F)
+ where F: FnOnce(Vec<A>, A)
+{
+}
+
+fn expect_free_supply_free<'x>(x: &'x u32) {
+ with_closure(|mut x: Vec<_>, y| {
+ // Shows that the call to `x.push()` is influencing type of `y`...
+ x.push(22_u32);
+
+ // ...since we now know the type of `y` and can resolve the method call.
+ let _ = y.wrapping_add(1);
+ });
+}
+
+fn main() { }
diff --git a/tests/ui/functions-closures/closure-expected-type/issue-38714.rs b/tests/ui/functions-closures/closure-expected-type/issue-38714.rs
new file mode 100644
index 000000000..e97785b5c
--- /dev/null
+++ b/tests/ui/functions-closures/closure-expected-type/issue-38714.rs
@@ -0,0 +1,19 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+struct UsizeRef<'a> {
+ a: &'a usize
+}
+
+type RefTo = Box<dyn for<'r> Fn(&'r Vec<usize>) -> UsizeRef<'r>>;
+
+fn ref_to<'a>(vec: &'a Vec<usize>) -> UsizeRef<'a> {
+ UsizeRef{ a: &vec[0]}
+}
+
+fn main() {
+ // Regression test: this was causing ICEs; it should compile.
+ let a: RefTo = Box::new(|vec: &Vec<usize>| {
+ UsizeRef{ a: &vec[0] }
+ });
+}
diff --git a/tests/ui/functions-closures/closure-expected-type/supply-just-return-type.rs b/tests/ui/functions-closures/closure-expected-type/supply-just-return-type.rs
new file mode 100644
index 000000000..e9964531c
--- /dev/null
+++ b/tests/ui/functions-closures/closure-expected-type/supply-just-return-type.rs
@@ -0,0 +1,26 @@
+// run-pass
+fn with_closure<F, R>(f: F) -> Result<char, R>
+ where F: FnOnce(&char) -> Result<char, R>,
+{
+ f(&'a')
+}
+
+fn main() {
+ // Test that supplying the `-> Result<char, ()>` manually here
+ // (which is needed to constrain `R`) still allows us to figure
+ // out that the type of `x` is `&'a char` where `'a` is bound in
+ // the closure (if we didn't, we'd get a type-error because
+ // `with_closure` requires a bound region).
+ //
+ // This pattern was found in the wild.
+ let z = with_closure(|x| -> Result<char, ()> { Ok(*x) });
+ assert_eq!(z.unwrap(), 'a');
+
+ // It also works with `_`:
+ let z = with_closure(|x: _| -> Result<char, ()> { Ok(*x) });
+ assert_eq!(z.unwrap(), 'a');
+
+ // It also works with `&_`:
+ let z = with_closure(|x: &_| -> Result<char, ()> { Ok(*x) });
+ assert_eq!(z.unwrap(), 'a');
+}
diff --git a/tests/ui/functions-closures/closure-expected-type/supply-nothing.rs b/tests/ui/functions-closures/closure-expected-type/supply-nothing.rs
new file mode 100644
index 000000000..8665cfc21
--- /dev/null
+++ b/tests/ui/functions-closures/closure-expected-type/supply-nothing.rs
@@ -0,0 +1,11 @@
+// run-pass
+fn with_closure<F>(f: F) -> u32
+ where F: FnOnce(&u32, &u32) -> u32
+{
+ f(&22, &44)
+}
+
+fn main() {
+ let z = with_closure(|x, y| x + y).wrapping_add(1);
+ assert_eq!(z, 22 + 44 + 1);
+}