about summary refs log tree commit diff
path: root/tests/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs')
-rw-r--r--tests/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/tests/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs b/tests/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs
new file mode 100644
index 00000000000..5251eeee8bb
--- /dev/null
+++ b/tests/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs
@@ -0,0 +1,50 @@
+// edition:2018
+// check-pass
+
+trait Trait<'a, 'b> {}
+impl<T> Trait<'_, '_> for T {}
+
+// `Invert<'a> <: Invert<'b>` if `'b: 'a`, unlike most types.
+//
+// I am purposefully avoiding the terms co- and contra-variant because
+// their application to regions depends on how you interpreted Rust
+// regions. -nikomatsakis
+struct Invert<'a>(fn(&'a u8));
+
+fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e>
+where
+    'c: 'a,
+    'c: 'b,
+    'd: 'c,
+{
+    // Representing the where clauses as a graph, where `A: B` is an
+    // edge `B -> A`:
+    //
+    // ```
+    // 'a -> 'c -> 'd
+    //        ^
+    //        |
+    //       'b
+    // ```
+    //
+    // Meanwhile we return a value &'0 u8 where we have the constraints:
+    //
+    // ```
+    // '0: 'a
+    // '0: 'b
+    // '0 in ['d, 'e]
+    // ```
+    //
+    // Here, ignoring the "in" constraint, the minimal choice for `'0`
+    // is `'c`, but that is not in the "in set". Still, that reduces
+    // the range of options in the "in set" to just `'d` (`'e: 'c`
+    // does not hold).
+    let p = if condition() { a } else { b };
+    p
+}
+
+fn condition() -> bool {
+    true
+}
+
+fn main() {}