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