about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/nll/member-constraints/non-root-universe-existential-1.rs29
-rw-r--r--tests/ui/nll/member-constraints/non-root-universe-existential-2.rs31
2 files changed, 60 insertions, 0 deletions
diff --git a/tests/ui/nll/member-constraints/non-root-universe-existential-1.rs b/tests/ui/nll/member-constraints/non-root-universe-existential-1.rs
new file mode 100644
index 00000000000..39dbfebce10
--- /dev/null
+++ b/tests/ui/nll/member-constraints/non-root-universe-existential-1.rs
@@ -0,0 +1,29 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+trait Proj<'a> {
+    type Assoc;
+}
+
+impl<'a, 'b, F: FnOnce() -> &'b ()> Proj<'a> for F {
+    type Assoc = ();
+}
+
+fn is_proj<F: for<'a> Proj<'a>>(f: F) {}
+
+fn define<'a>() -> impl Sized + use<'a> {
+    // This defines the RPIT to `&'unconstrained_b ()`, an inference
+    // variable which is in a higher universe as gets created inside
+    // of the binder of `F: for<'a> Proj<'a>`. This previously caused
+    // us to not apply member constraints.
+    //
+    // This was unnecessary. It is totally acceptable for member regions
+    // to be able to name placeholders from higher universes, as long as
+    // they don't actually do so.
+    is_proj(define::<'a>);
+    &()
+}
+
+fn main() {}
diff --git a/tests/ui/nll/member-constraints/non-root-universe-existential-2.rs b/tests/ui/nll/member-constraints/non-root-universe-existential-2.rs
new file mode 100644
index 00000000000..c5ddde0d7d8
--- /dev/null
+++ b/tests/ui/nll/member-constraints/non-root-universe-existential-2.rs
@@ -0,0 +1,31 @@
+//@ check-pass
+
+// Unlike `non-root-universe-existential-1.rs` this previously
+// compiled as it simply didn't define the hidden type of
+// `impl Iterator` when projecting through it. We will do so
+// with the new solver. Further minimizing this is challenging.
+
+struct Type(Vec<Type>);
+enum TypeTreeValueIter<'a, T> {
+    Once(T),
+    Ref(&'a ()),
+}
+
+impl<'a, T> Iterator for TypeTreeValueIter<'a, T> {
+    type Item = T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        loop {}
+    }
+}
+
+fn item<I: Iterator<Item: Iterator>>(x: I) -> <I::Item as Iterator>::Item {
+    loop {}
+}
+
+fn get_type_tree_values<'a>(ty: &'a Type) -> impl Iterator<Item = &'a Type> {
+    let _: &'a Type = item(std::iter::once(ty).map(get_type_tree_values));
+    TypeTreeValueIter::<'a, &'a Type>::Once(ty)
+}
+
+fn main() {}