summaryrefslogtreecommitdiffstats
path: root/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/nll/closure-requirements/propagate-despite-same-free-region.rs')
-rw-r--r--tests/ui/nll/closure-requirements/propagate-despite-same-free-region.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.rs b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.rs
new file mode 100644
index 000000000..704a026d2
--- /dev/null
+++ b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.rs
@@ -0,0 +1,50 @@
+// Test where we might in theory be able to see that the relationship
+// between two bound regions is true within closure and hence have no
+// need to propagate; but in fact we do because identity of free
+// regions is erased.
+
+// compile-flags:-Zverbose
+// check-pass
+
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+// In theory, callee knows that:
+//
+// 'x: 'a
+// 'a: 'y
+//
+// and hence could satisfy that `'x: 'y` locally. However, in our
+// checking, we ignore the precise free regions that come into the
+// region and just assign each position a distinct universally bound
+// region. Hence, we propagate a constraint to our caller that will
+// wind up being solvable.
+fn establish_relationships<'a, F>(
+ _cell_a: Cell<&'a u32>,
+ _closure: F,
+) where
+ F: for<'x, 'y> FnMut(
+ Cell<&'a &'x u32>, // shows that 'x: 'a
+ Cell<&'y &'a u32>, // shows that 'a: 'y
+ Cell<&'x u32>,
+ Cell<&'y u32>,
+ ),
+{
+}
+
+fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) {}
+
+#[rustc_regions]
+fn supply<'a>(cell_a: Cell<&'a u32>) {
+ establish_relationships(
+ cell_a,
+ |_outlives1, _outlives2, x, y| {
+ // Only works if 'x: 'y:
+ let p = x.get();
+ demand_y(x, y, p)
+ },
+ );
+}
+
+fn main() {}