about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2021-05-12 11:46:14 -0400
committerNiko Matsakis <niko@alum.mit.edu>2021-05-13 04:49:20 -0400
commitc7cb72828d2b4cd6f2b138a1b4efbdf6116901b5 (patch)
tree4822b62d1e98329b1ed9796f769ddc2e2f484fd0 /src
parent506e75cbf8cb5305e49a41326307004ca3976029 (diff)
downloadrust-c7cb72828d2b4cd6f2b138a1b4efbdf6116901b5.tar.gz
rust-c7cb72828d2b4cd6f2b138a1b4efbdf6116901b5.zip
introduce a unit testing feature `rustc_evaluate_where_clauses`
This attribute will cause us to invoke evaluate on every where clause of an
invoked function and to generate an error with the result.

Without this, it is very difficult to observe the effects of invoking the trait
evaluator.
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/cycle-me.rs31
-rw-r--r--src/test/ui/traits/issue-83538-tainted-cache-after-cycle.rs66
-rw-r--r--src/test/ui/traits/issue-83538-tainted-cache-after-cycle.stderr38
3 files changed, 135 insertions, 0 deletions
diff --git a/src/test/ui/cycle-me.rs b/src/test/ui/cycle-me.rs
new file mode 100644
index 00000000000..eb1ffe51ffc
--- /dev/null
+++ b/src/test/ui/cycle-me.rs
@@ -0,0 +1,31 @@
+#![feature(rustc_attrs)]
+
+// A (reached depth 0)
+//   ...
+//      B // depth 1 -- reached depth = 0
+//          C // depth 2 -- reached depth = 1 (should be 0)
+//              B
+//          A // depth 0
+//   D (reached depth 1)
+//      C (cache -- reached depth = 2)
+
+struct A {
+    b: B,
+    c: C,
+}
+
+struct B {
+    c: C,
+    a: Option<Box<A>>,
+}
+
+struct C {
+    b: Option<Box<B>>,
+}
+
+#[rustc_evaluate_where_clauses]
+fn test<X: Send>() {}
+
+fn main() {
+    test::<A>();
+}
diff --git a/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.rs b/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.rs
new file mode 100644
index 00000000000..1b357575cb8
--- /dev/null
+++ b/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.rs
@@ -0,0 +1,66 @@
+// Regression test for issue #83538. The problem here is that we have
+// two cycles:
+//
+// * `Ty` embeds `Box<Ty>` indirectly, which depends on `Global: 'static`, which is OkModuloRegions.
+// * But `Ty` also references `First`, which has a cycle on itself. That should just be `Ok`.
+//
+// But our caching mechanism was blending both cycles and giving the incorrect result.
+
+#![feature(rustc_attrs)]
+#![allow(bad_style)]
+
+struct First {
+    b: Vec<First>,
+}
+
+pub struct Second {
+    d: Vec<First>,
+}
+
+struct Third<f> {
+    g: Vec<f>,
+}
+
+enum Ty {
+    j(Fourth, Fifth, Sixth),
+}
+
+struct Fourth {
+    o: Vec<Ty>,
+}
+
+struct Fifth {
+    bounds: First,
+}
+
+struct Sixth {
+    p: Box<Ty>,
+}
+
+#[rustc_evaluate_where_clauses]
+fn forward()
+where
+    Vec<First>: Unpin,
+    Third<Ty>: Unpin,
+{
+}
+
+#[rustc_evaluate_where_clauses]
+fn reverse()
+where
+    Third<Ty>: Unpin,
+    Vec<First>: Unpin,
+{
+}
+
+fn main() {
+    // The only ERROR included here is the one that is totally wrong:
+
+    forward();
+    //~^ ERROR evaluate(Binder(TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+    //~| ERROR evaluate(Binder(TraitPredicate(<Third<Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+
+    reverse();
+    //~^ ERROR evaluate(Binder(TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+    //~| ERROR evaluate(Binder(TraitPredicate(<Third<Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+}
diff --git a/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.stderr b/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.stderr
new file mode 100644
index 00000000000..82e00c3b97f
--- /dev/null
+++ b/src/test/ui/traits/issue-83538-tainted-cache-after-cycle.stderr
@@ -0,0 +1,38 @@
+error: evaluate(Binder(TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+  --> $DIR/issue-83538-tainted-cache-after-cycle.rs:59:5
+   |
+LL |     Vec<First>: Unpin,
+   |                 ----- predicate
+...
+LL |     forward();
+   |     ^^^^^^^
+
+error: evaluate(Binder(TraitPredicate(<Third<Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+  --> $DIR/issue-83538-tainted-cache-after-cycle.rs:59:5
+   |
+LL |     Third<Ty>: Unpin,
+   |                ----- predicate
+...
+LL |     forward();
+   |     ^^^^^^^
+
+error: evaluate(Binder(TraitPredicate(<Third<Ty> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+  --> $DIR/issue-83538-tainted-cache-after-cycle.rs:63:5
+   |
+LL |     Third<Ty>: Unpin,
+   |                ----- predicate
+...
+LL |     reverse();
+   |     ^^^^^^^
+
+error: evaluate(Binder(TraitPredicate(<std::vec::Vec<First> as std::marker::Unpin>), [])) = Ok(EvaluatedToOkModuloRegions)
+  --> $DIR/issue-83538-tainted-cache-after-cycle.rs:63:5
+   |
+LL |     Vec<First>: Unpin,
+   |                 ----- predicate
+...
+LL |     reverse();
+   |     ^^^^^^^
+
+error: aborting due to 4 previous errors
+