]> git.proxmox.com Git - rustc.git/blame - src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.fixed
New upstream version 1.55.0+dfsg1
[rustc.git] / src / test / ui / closures / 2229_closure_analysis / migrations / significant_drop.fixed
CommitLineData
cdc7bbd5 1// run-rustfix
136023e0 2#![deny(rust_2021_incompatible_closure_captures)]
cdc7bbd5
XL
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 = || { let _ = (&t, &t1, &t2);
136023e0
XL
26 //~^ ERROR: drop order
27 //~| NOTE: for more information, see
28 //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured
cdc7bbd5 29 let _t = t.0;
136023e0 30 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
cdc7bbd5 31 let _t1 = t1.0;
136023e0 32 //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
cdc7bbd5 33 let _t2 = t2.0;
136023e0 34 //~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0`
cdc7bbd5
XL
35 };
36
37 c();
38}
136023e0
XL
39//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
40//~| NOTE: in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
41//~| NOTE: in Rust 2018, `t2` would be dropped here, but in Rust 2021, only `t2.0` would be dropped here alongside the closure
cdc7bbd5
XL
42
43// String implements drop and therefore should be migrated.
44// But in this test cases, `t2` is completely captured and when it is dropped won't be affected
45fn test2_only_precise_paths_need_migration() {
46 let t = (Foo(0), Foo(0));
47 let t1 = (Foo(0), Foo(0));
48 let t2 = (Foo(0), Foo(0));
49
50 let c = || { let _ = (&t, &t1);
136023e0
XL
51 //~^ ERROR: drop order
52 //~| NOTE: for more information, see
53 //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
cdc7bbd5 54 let _t = t.0;
136023e0 55 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
cdc7bbd5 56 let _t1 = t1.0;
136023e0 57 //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
cdc7bbd5
XL
58 let _t2 = t2;
59 };
60
61 c();
62}
136023e0
XL
63//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
64//~| NOTE: in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.0` would be dropped here alongside the closure
cdc7bbd5
XL
65
66// If a variable would've not been captured by value then it would've not been
67// dropped with the closure and therefore doesn't need migration.
68fn test3_only_by_value_need_migration() {
69 let t = (Foo(0), Foo(0));
70 let t1 = (Foo(0), Foo(0));
71 let c = || { let _ = &t;
136023e0
XL
72 //~^ ERROR: drop order
73 //~| NOTE: for more information, see
74 //~| HELP: add a dummy let to cause `t` to be fully captured
cdc7bbd5 75 let _t = t.0;
136023e0 76 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
cdc7bbd5
XL
77 println!("{:?}", t1.1);
78 };
79
80 c();
81}
136023e0 82//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
cdc7bbd5
XL
83
84// The root variable might not implement drop themselves but some path starting
85// at the root variable might implement Drop.
86//
87// If this path isn't captured we need to migrate for the root variable.
88fn test4_type_contains_drop_need_migration() {
89 let t = ConstainsDropField(Foo(0), Foo(0));
90
91 let c = || { let _ = &t;
136023e0
XL
92 //~^ ERROR: drop order
93 //~| NOTE: for more information, see
94 //~| HELP: add a dummy let to cause `t` to be fully captured
cdc7bbd5 95 let _t = t.0;
136023e0 96 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
cdc7bbd5
XL
97 };
98
99 c();
100}
136023e0 101//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
cdc7bbd5
XL
102
103// Test migration analysis in case of Drop + Non Drop aggregates.
104// Note we need migration here only because the non-copy (because Drop type) is captured,
105// otherwise we won't need to, since we can get away with just by ref capture in that case.
106fn test5_drop_non_drop_aggregate_need_migration() {
107 let t = (Foo(0), Foo(0), 0i32);
108
109 let c = || { let _ = &t;
136023e0
XL
110 //~^ ERROR: drop order
111 //~| NOTE: for more information, see
112 //~| HELP: add a dummy let to cause `t` to be fully captured
cdc7bbd5 113 let _t = t.0;
136023e0 114 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
cdc7bbd5
XL
115 };
116
117 c();
118}
136023e0 119//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
cdc7bbd5
XL
120
121// Test migration analysis in case of Significant and Insignificant Drop aggregates.
122fn test6_significant_insignificant_drop_aggregate_need_migration() {
123 let t = (Foo(0), String::new());
124
125 let c = || { let _ = &t;
136023e0
XL
126 //~^ ERROR: drop order
127 //~| NOTE: for more information, see
128 //~| HELP: add a dummy let to cause `t` to be fully captured
cdc7bbd5 129 let _t = t.1;
136023e0 130 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
cdc7bbd5
XL
131 };
132
133 c();
134}
136023e0 135//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
cdc7bbd5
XL
136
137// Since we are using a move closure here, both `t` and `t1` get moved
138// even though they are being used by ref inside the closure.
139fn test7_move_closures_non_copy_types_might_need_migration() {
140 let t = (Foo(0), Foo(0));
141 let t1 = (Foo(0), Foo(0), Foo(0));
142
143 let c = move || { let _ = (&t1, &t);
136023e0
XL
144 //~^ ERROR: drop order
145 //~| NOTE: for more information, see
146 //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
cdc7bbd5 147 println!("{:?} {:?}", t1.1, t.1);
136023e0
XL
148 //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.1`
149 //~| NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.1`
cdc7bbd5
XL
150 };
151
152 c();
153}
136023e0
XL
154//~^ NOTE: in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.1` would be dropped here alongside the closure
155//~| NOTE: in Rust 2018, `t1` would be dropped here, but in Rust 2021, only `t1.1` would be dropped here alongside the closure
156
157
158fn test8_drop_order_and_blocks() {
159 {
160 let tuple =
161 (String::from("foo"), String::from("bar"));
162 {
163 let c = || { let _ = &tuple;
164 //~^ ERROR: drop order
165 //~| NOTE: for more information, see
166 //~| HELP: add a dummy let to cause `tuple` to be fully captured
167 tuple.0;
168 //~^ NOTE: in Rust 2018, closure captures all of `tuple`, but in Rust 2021, it only captures `tuple.0`
169 };
170
171 c();
172 }
173 //~^ NOTE: in Rust 2018, `tuple` would be dropped here, but in Rust 2021, only `tuple.0` would be dropped here alongside the closure
174 }
175}
176
177fn test9_drop_order_and_nested_closures() {
178 let tuple =
179 (String::from("foo"), String::from("bar"));
180 let b = || {
181 let c = || { let _ = &tuple;
182 //~^ ERROR: drop order
183 //~| NOTE: for more information, see
184 //~| HELP: add a dummy let to cause `tuple` to be fully captured
185 tuple.0;
186 //~^ NOTE: in Rust 2018, closure captures all of `tuple`, but in Rust 2021, it only captures `tuple.0`
187 };
188
189 c();
190 };
191 //~^ NOTE: in Rust 2018, `tuple` would be dropped here, but in Rust 2021, only `tuple.0` would be dropped here alongside the closure
192
193 b();
194}
cdc7bbd5
XL
195
196fn main() {
197 test1_all_need_migration();
198 test2_only_precise_paths_need_migration();
199 test3_only_by_value_need_migration();
200 test4_type_contains_drop_need_migration();
201 test5_drop_non_drop_aggregate_need_migration();
202 test6_significant_insignificant_drop_aggregate_need_migration();
203 test7_move_closures_non_copy_types_might_need_migration();
136023e0
XL
204 test8_drop_order_and_blocks();
205 test9_drop_order_and_nested_closures();
cdc7bbd5 206}