about summary refs log tree commit diff
path: root/tests/ui/traits/cache-reached-depth-ice.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/traits/cache-reached-depth-ice.rs')
-rw-r--r--tests/ui/traits/cache-reached-depth-ice.rs45
1 files changed, 45 insertions, 0 deletions
diff --git a/tests/ui/traits/cache-reached-depth-ice.rs b/tests/ui/traits/cache-reached-depth-ice.rs
new file mode 100644
index 00000000000..c36ac08579b
--- /dev/null
+++ b/tests/ui/traits/cache-reached-depth-ice.rs
@@ -0,0 +1,45 @@
+#![feature(rustc_attrs)]
+
+// Test for a particular corner case where the evaluation
+// cache can get out of date. The problem here is that
+// when we cache C, we have observed that it reaches
+// to depth 2 (the node for B), but we later realize
+// that B itself depends on A (reached depth 0). We
+// failed to update the depth for C transitively, which
+// resulted in an assertion failure when it was referenced
+// from D.
+//
+// A (reached depth 0)
+//   E
+//      B // depth 2 -- reached depth = 0
+//          C // depth 3 -- reached depth = 2 (should be 0)
+//              B
+//          A // depth 0
+//   D (depth 1)
+//      C (cache -- reached depth = 2)
+
+struct A {
+    e: E,
+    d: C,
+}
+
+struct E {
+    b: B,
+}
+
+struct B {
+    a: Option<Box<A>>,
+    c: C,
+}
+
+struct C {
+    b: Option<Box<B>>,
+}
+
+#[rustc_evaluate_where_clauses]
+fn test<X: ?Sized + Send>() {}
+
+fn main() {
+    test::<A>();
+    //~^ ERROR evaluate(Binder(TraitPredicate(<A as std::marker::Send>, polarity:Positive), [])) = Ok(EvaluatedToOk)
+}