]> git.lizzy.rs Git - rust.git/commitdiff
Tests for precise lint analysis
authorAman Arora <me@aman-arora.com>
Thu, 4 Feb 2021 23:50:32 +0000 (18:50 -0500)
committerAman Arora <me@aman-arora.com>
Tue, 9 Feb 2021 07:53:59 +0000 (02:53 -0500)
src/test/ui/closures/2229_closure_analysis/migrations/precise.rs [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr [new file with mode: 0644]
src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs [new file with mode: 0644]

diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs b/src/test/ui/closures/2229_closure_analysis/migrations/precise.rs
new file mode 100644 (file)
index 0000000..79702cc
--- /dev/null
@@ -0,0 +1,78 @@
+#![deny(disjoint_capture_drop_reorder)]
+//~^ NOTE: the lint level is defined here
+
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
+struct ConstainsDropField(Foo, Foo);
+
+#[derive(Debug)]
+struct ContainsAndImplsDrop(Foo);
+impl Drop for ContainsAndImplsDrop {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
+// Test that even if all paths starting at root variable that implement Drop are captured,
+// the lint is triggered if the root variable implements drop and isn't captured.
+fn test_precise_analysis_parent_root_impl_drop_not_captured() {
+    let t = ContainsAndImplsDrop(Foo(10));
+
+    let c = || {
+    //~^ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~| NOTE: drop(&(t));
+        let _t = t.0;
+    };
+
+    c();
+}
+
+// Test that lint is triggered if a path that implements Drop is not captured by move
+fn test_precise_analysis_drop_paths_not_captured_by_move() {
+    let t = ConstainsDropField(Foo(10), Foo(20));
+
+    let c = || {
+    //~^ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~| NOTE: drop(&(t));
+        let _t = t.0;
+        let _t = &t.1;
+    };
+
+    c();
+}
+
+struct S;
+impl Drop for S {
+    fn drop(&mut self) {
+    }
+}
+
+struct T(S, S);
+struct U(T, T);
+
+// Test precise analysis for the lint works with paths longer than one.
+fn test_precise_analysis_long_path_missing() {
+    let u = U(T(S, S), T(S, S));
+
+    let c = || {
+    //~^ERROR: drop order affected for closure because of `capture_disjoint_fields`
+    //~| NOTE: drop(&(u));
+        let _x = u.0.0;
+        let _x = u.0.1;
+        let _x = u.1.0;
+    };
+
+    c();
+}
+
+fn main() {
+    test_precise_analysis_parent_root_impl_drop_not_captured();
+    test_precise_analysis_drop_paths_not_captured_by_move();
+    test_precise_analysis_long_path_missing();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr
new file mode 100644 (file)
index 0000000..968ca39
--- /dev/null
@@ -0,0 +1,49 @@
+error: drop order affected for closure because of `capture_disjoint_fields`
+  --> $DIR/precise.rs:27:13
+   |
+LL |       let c = || {
+   |  _____________^
+LL | |
+LL | |
+LL | |         let _t = t.0;
+LL | |     };
+   | |_____^
+   |
+note: the lint level is defined here
+  --> $DIR/precise.rs:1:9
+   |
+LL | #![deny(disjoint_capture_drop_reorder)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: drop(&(t));
+
+error: drop order affected for closure because of `capture_disjoint_fields`
+  --> $DIR/precise.rs:40:13
+   |
+LL |       let c = || {
+   |  _____________^
+LL | |
+LL | |
+LL | |         let _t = t.0;
+LL | |         let _t = &t.1;
+LL | |     };
+   | |_____^
+   |
+   = note: drop(&(t));
+
+error: drop order affected for closure because of `capture_disjoint_fields`
+  --> $DIR/precise.rs:63:13
+   |
+LL |       let c = || {
+   |  _____________^
+LL | |
+LL | |
+LL | |         let _x = u.0.0;
+LL | |         let _x = u.0.1;
+LL | |         let _x = u.1.0;
+LL | |     };
+   | |_____^
+   |
+   = note: drop(&(u));
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs b/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs
new file mode 100644 (file)
index 0000000..8af4850
--- /dev/null
@@ -0,0 +1,105 @@
+// run-pass
+
+#![deny(disjoint_capture_drop_reorder)]
+
+#[derive(Debug)]
+struct Foo(i32);
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
+struct ConstainsDropField(Foo, Foo);
+
+// Test that if all paths starting at root variable that implement Drop are captured
+// then it doesn't trigger the lint.
+fn test_precise_analysis_simple_1() {
+    let t = (Foo(10), Foo(20), Foo(30));
+
+    let c = || {
+        let _t = t.0;
+        let _t = t.1;
+        let _t = t.2;
+    };
+
+    c();
+}
+
+// Test that if all paths starting at root variable that implement Drop are captured
+// then it doesn't trigger the lint.
+fn test_precise_analysis_simple_2() {
+    let t = ConstainsDropField(Foo(10), Foo(20));
+
+    let c = || {
+        let _t = t.0;
+        let _t = t.1;
+    };
+
+    c();
+}
+
+#[derive(Debug)]
+struct ContainsAndImplsDrop(Foo);
+impl Drop for ContainsAndImplsDrop {
+    fn drop(&mut self) {
+        println!("{:?} dropped", self.0);
+    }
+}
+
+// If a path isn't directly captured but requires Drop, then this tests that migrations aren't
+// needed if the a parent to that path is captured.
+fn test_precise_analysis_parent_captured_1() {
+    let t = ConstainsDropField(Foo(10), Foo(20));
+
+    let c = || {
+        let _t = t;
+    };
+
+    c();
+}
+
+// If a path isn't directly captured but requires Drop, then this tests that migrations aren't
+// needed if the a parent to that path is captured.
+fn test_precise_analysis_parent_captured_2() {
+    let t = ContainsAndImplsDrop(Foo(10));
+
+    let c = || {
+        let _t = t;
+    };
+
+    c();
+}
+
+struct S;
+impl Drop for S {
+    fn drop(&mut self) {
+    }
+}
+
+struct T(S, S);
+struct U(T, T);
+
+// Test that if the path is longer than just one element, precise analysis works correctly.
+fn test_precise_analysis_long_path() {
+    let u = U(T(S, S), T(S, S));
+
+    let c = || {
+        let _x = u.0.0;
+        let _x = u.0.1;
+        let _x = u.1.0;
+        let _x = u.1.1;
+    };
+
+    c();
+}
+
+fn main() {
+    test_precise_analysis_simple_1();
+    test_precise_analysis_simple_2();
+
+    test_precise_analysis_parent_captured_1();
+    test_precise_analysis_parent_captured_2();
+
+    test_precise_analysis_long_path();
+}