]> git.proxmox.com Git - rustc.git/blame - src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / src / test / ui / closures / 2229_closure_analysis / migrations / significant_drop.rs
CommitLineData
cdc7bbd5 1// run-rustfix
5869c6ff
XL
2#![deny(disjoint_capture_drop_reorder)]
3//~^ NOTE: the lint level is defined here
4
5// Test cases for types that implement a significant drop (user defined)
6
7#[derive(Debug)]
8struct Foo(i32);
9impl Drop for Foo {
10 fn drop(&mut self) {
11 println!("{:?} dropped", self.0);
12 }
13}
14
15#[derive(Debug)]
16struct ConstainsDropField(Foo, Foo);
17
18// `t` needs Drop because one of its elements needs drop,
19// therefore precise capture might affect drop ordering
20fn test1_all_need_migration() {
21 let t = (Foo(0), Foo(0));
22 let t1 = (Foo(0), Foo(0));
23 let t2 = (Foo(0), Foo(0));
24
25 let c = || {
cdc7bbd5
XL
26 //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
27 //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
5869c6ff
XL
28 let _t = t.0;
29 let _t1 = t1.0;
30 let _t2 = t2.0;
31 };
32
33 c();
34}
35
36// String implements drop and therefore should be migrated.
37// But in this test cases, `t2` is completely captured and when it is dropped won't be affected
38fn test2_only_precise_paths_need_migration() {
39 let t = (Foo(0), Foo(0));
40 let t1 = (Foo(0), Foo(0));
41 let t2 = (Foo(0), Foo(0));
42
43 let c = || {
cdc7bbd5
XL
44 //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
45 //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
5869c6ff
XL
46 let _t = t.0;
47 let _t1 = t1.0;
48 let _t2 = t2;
49 };
50
51 c();
52}
53
54// If a variable would've not been captured by value then it would've not been
55// dropped with the closure and therefore doesn't need migration.
56fn test3_only_by_value_need_migration() {
57 let t = (Foo(0), Foo(0));
58 let t1 = (Foo(0), Foo(0));
59 let c = || {
cdc7bbd5
XL
60 //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
61 //~| HELP: add a dummy let to cause `t` to be fully captured
5869c6ff
XL
62 let _t = t.0;
63 println!("{:?}", t1.1);
64 };
65
66 c();
67}
68
69// The root variable might not implement drop themselves but some path starting
70// at the root variable might implement Drop.
71//
72// If this path isn't captured we need to migrate for the root variable.
73fn test4_type_contains_drop_need_migration() {
74 let t = ConstainsDropField(Foo(0), Foo(0));
75
76 let c = || {
cdc7bbd5
XL
77 //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
78 //~| HELP: add a dummy let to cause `t` to be fully captured
5869c6ff
XL
79 let _t = t.0;
80 };
81
82 c();
83}
84
85// Test migration analysis in case of Drop + Non Drop aggregates.
86// Note we need migration here only because the non-copy (because Drop type) is captured,
87// otherwise we won't need to, since we can get away with just by ref capture in that case.
88fn test5_drop_non_drop_aggregate_need_migration() {
89 let t = (Foo(0), Foo(0), 0i32);
90
91 let c = || {
cdc7bbd5
XL
92 //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
93 //~| HELP: add a dummy let to cause `t` to be fully captured
5869c6ff
XL
94 let _t = t.0;
95 };
96
97 c();
98}
99
100// Test migration analysis in case of Significant and Insignificant Drop aggregates.
101fn test6_significant_insignificant_drop_aggregate_need_migration() {
5869c6ff
XL
102 let t = (Foo(0), String::new());
103
104 let c = || {
cdc7bbd5
XL
105 //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
106 //~| HELP: add a dummy let to cause `t` to be fully captured
5869c6ff
XL
107 let _t = t.1;
108 };
109
110 c();
111}
112
113// Since we are using a move closure here, both `t` and `t1` get moved
114// even though they are being used by ref inside the closure.
115fn test7_move_closures_non_copy_types_might_need_migration() {
116 let t = (Foo(0), Foo(0));
117 let t1 = (Foo(0), Foo(0), Foo(0));
118
119 let c = move || {
cdc7bbd5
XL
120 //~^ ERROR: drop order affected for closure because of `capture_disjoint_fields`
121 //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
5869c6ff
XL
122 println!("{:?} {:?}", t1.1, t.1);
123 };
124
125 c();
126}
127
128fn main() {
129 test1_all_need_migration();
130 test2_only_precise_paths_need_migration();
131 test3_only_by_value_need_migration();
132 test4_type_contains_drop_need_migration();
133 test5_drop_non_drop_aggregate_need_migration();
134 test6_significant_insignificant_drop_aggregate_need_migration();
135 test7_move_closures_non_copy_types_might_need_migration();
136}