about summary refs log tree commit diff
path: root/src/test/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui')
-rw-r--r--src/test/ui/hrtb/issue-46989.rs42
-rw-r--r--src/test/ui/hrtb/issue-57639.rs29
-rw-r--r--src/test/ui/hrtb/issue-58451.rs13
3 files changed, 84 insertions, 0 deletions
diff --git a/src/test/ui/hrtb/issue-46989.rs b/src/test/ui/hrtb/issue-46989.rs
new file mode 100644
index 00000000000..2c859055458
--- /dev/null
+++ b/src/test/ui/hrtb/issue-46989.rs
@@ -0,0 +1,42 @@
+// Regression test for #46989:
+//
+// In the move to universes, this test started passing.
+// It is not necessarily WRONG to do so, but it was a bit
+// surprising. The reason that it passed is that when we were
+// asked to prove that
+//
+//     for<'a> fn(&'a i32): Foo
+//
+// we were able to use the impl below to prove
+//
+//     fn(&'empty i32): Foo
+//
+// and then we were able to prove that
+//
+//     fn(&'empty i32) = for<'a> fn(&'a i32)
+//
+// This last fact is somewhat surprising, but essentially "falls out"
+// from handling variance correctly. In particular, consider the subtyping
+// relations. First:
+//
+//     fn(&'empty i32) <: for<'a> fn(&'a i32)
+//
+// This holds because -- intuitively -- a fn that takes a reference but doesn't use
+// it can be given a reference with any lifetime. Similarly, the opposite direction:
+//
+//     for<'a> fn(&'a i32) <: fn(&'empty i32)
+//
+// holds because 'a can be instantiated to 'empty.
+
+trait Foo {
+
+}
+
+impl<A> Foo for fn(A) { }
+
+fn assert_foo<T: Foo>() {}
+
+fn main() {
+    assert_foo::<fn(&i32)>();
+    //~^ ERROR the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied
+}
diff --git a/src/test/ui/hrtb/issue-57639.rs b/src/test/ui/hrtb/issue-57639.rs
new file mode 100644
index 00000000000..4bcaef3616b
--- /dev/null
+++ b/src/test/ui/hrtb/issue-57639.rs
@@ -0,0 +1,29 @@
+// Regression test for #57639:
+//
+// In the move to universes, this test stopped working. The problem
+// was that when the trait solver was asked to prove `for<'a> T::Item:
+// Foo<'a>` as part of WF checking, it wound up "eagerly committing"
+// to the where clause, which says that `T::Item: Foo<'a>`, but it
+// should instead have been using the bound found in the trait
+// declaration. Pre-universe, this used to work out ok because we got
+// "eager errors" due to the leak check.
+//
+// See [this comment on GitHub][c] for more details.
+//
+// run-pass
+//
+// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861
+
+trait Foo<'a> {}
+
+trait Bar {
+    type Item: for<'a> Foo<'a>;
+}
+
+fn foo<'a, T>(_: T)
+where
+    T: Bar,
+    T::Item: Foo<'a>,
+{}
+
+fn main() { }
diff --git a/src/test/ui/hrtb/issue-58451.rs b/src/test/ui/hrtb/issue-58451.rs
new file mode 100644
index 00000000000..7ca6914d2ea
--- /dev/null
+++ b/src/test/ui/hrtb/issue-58451.rs
@@ -0,0 +1,13 @@
+// Regression test for #58451:
+//
+// Error reporting here encountered an ICE in the shift to universes.
+
+fn f<I>(i: I)
+where
+    I: IntoIterator,
+    I::Item: for<'a> Into<&'a ()>,
+{}
+
+fn main() {
+    f(&[f()]);
+}