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