]>
Commit | Line | Data |
---|---|---|
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)] | |
8 | struct Foo(i32); | |
9 | impl Drop for Foo { | |
10 | fn drop(&mut self) { | |
11 | println!("{:?} dropped", self.0); | |
12 | } | |
13 | } | |
14 | ||
15 | #[derive(Debug)] | |
064997fb | 16 | struct 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 | |
20 | fn 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 | |
46 | fn 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. | |
70 | fn 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. | |
91 | fn 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. | |
110 | fn 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. | |
127 | fn 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. | |
145 | fn 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 | ||
165 | fn 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 | ||
185 | fn 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 |
206 | fn 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 |
218 | fn 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 | } |