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