summaryrefslogtreecommitdiffstats
path: root/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs')
-rw-r--r--src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs104
1 files changed, 104 insertions, 0 deletions
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
index 000000000..587d71c40
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise_no_migrations.rs
@@ -0,0 +1,104 @@
+// run-pass
+
+#![deny(rust_2021_incompatible_closure_captures)]
+
+#[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();
+}