2 #![deny(rust_2021_incompatible_closure_captures)]
3 //~^ NOTE: the lint level is defined here
5 // Test cases for types that implement a significant drop (user defined)
11 println!("{:?} dropped", self.0);
16 struct ConstainsDropField(Foo, #[allow(unused_tuple_struct_fields)] Foo);
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));
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
30 //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
32 //~^ NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0`
34 //~^ NOTE: in Rust 2018, this closure captures all of `t2`, but in Rust 2021, it will only capture `t2.0`
39 //~^ NOTE: in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
40 //~| NOTE: in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
41 //~| NOTE: in Rust 2018, `t2` is dropped here, but in Rust 2021, only `t2.0` will be dropped here as part of the closure
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
45 fn 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));
51 //~^ ERROR: drop order
52 //~| NOTE: for more information, see
53 //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured
55 //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
57 //~^ NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0`
63 //~^ NOTE: in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
64 //~| NOTE: in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
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.
68 fn test3_only_by_value_need_migration() {
69 let t = (Foo(0), Foo(0));
70 let t1 = (Foo(0), Foo(0));
72 //~^ ERROR: drop order
73 //~| NOTE: for more information, see
74 //~| HELP: add a dummy let to cause `t` to be fully captured
76 //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
77 println!("{:?}", t1.1);
82 //~^ NOTE: in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
84 // The root variable might not implement drop themselves but some path starting
85 // at the root variable might implement Drop.
87 // If this path isn't captured we need to migrate for the root variable.
88 fn test4_type_contains_drop_need_migration() {
89 let t = ConstainsDropField(Foo(0), Foo(0));
92 //~^ ERROR: drop order
93 //~| NOTE: for more information, see
94 //~| HELP: add a dummy let to cause `t` to be fully captured
96 //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
101 //~^ NOTE: in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
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.
106 fn test5_drop_non_drop_aggregate_need_migration() {
107 let t = (Foo(0), Foo(0), 0i32);
110 //~^ ERROR: drop order
111 //~| NOTE: for more information, see
112 //~| HELP: add a dummy let to cause `t` to be fully captured
114 //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0`
119 //~^ NOTE: in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
121 // Test migration analysis in case of Significant and Insignificant Drop aggregates.
122 fn test6_significant_insignificant_drop_aggregate_need_migration() {
123 let t = (Foo(0), String::new());
126 //~^ ERROR: drop order
127 //~| NOTE: for more information, see
128 //~| HELP: add a dummy let to cause `t` to be fully captured
130 //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.1`
135 //~^ NOTE: in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
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.
139 fn 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));
144 //~^ ERROR: drop order
145 //~| NOTE: for more information, see
146 //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured
147 println!("{:?} {:?}", t1.1, t.1);
148 //~^ NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.1`
149 //~| NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.1`
154 //~^ NOTE: in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
155 //~| NOTE: in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.1` will be dropped here as part of the closure
158 fn test8_drop_order_and_blocks() {
164 //~^ ERROR: drop order
165 //~| NOTE: for more information, see
166 //~| HELP: add a dummy let to cause `tuple` to be fully captured
168 //~^ NOTE: in Rust 2018, this closure captures all of `tuple`, but in Rust 2021, it will only capture `tuple.0`
173 //~^ NOTE: in Rust 2018, `tuple` is dropped here, but in Rust 2021, only `tuple.0` will be dropped here as part of the closure
177 fn test9_drop_order_and_nested_closures() {
182 //~^ ERROR: drop order
183 //~| NOTE: for more information, see
184 //~| HELP: add a dummy let to cause `tuple` to be fully captured
186 //~^ NOTE: in Rust 2018, this closure captures all of `tuple`, but in Rust 2021, it will only capture `tuple.0`
191 //~^ NOTE: in Rust 2018, `tuple` is dropped here, but in Rust 2021, only `tuple.0` will be dropped here as part of the closure
196 // Test that we migrate if drop order of Vec<T> would be affected if T is a significant drop type
197 fn test10_vec_of_significant_drop_type() {
199 let tup = (Foo(0), vec![Foo(3)]);
202 //~^ ERROR: drop order
203 //~| NOTE: for more information, see
204 //~| HELP: add a dummy let to cause `tup` to be fully captured
205 //~| NOTE: in Rust 2018, this closure captures all of `tup`, but in Rust 2021, it will only capture `tup.0`
207 //~^ NOTE: in Rust 2018, `tup` is dropped here, but in Rust 2021, only `tup.0` will be dropped here as part of the closure
210 test1_all_need_migration();
211 test2_only_precise_paths_need_migration();
212 test3_only_by_value_need_migration();
213 test4_type_contains_drop_need_migration();
214 test5_drop_non_drop_aggregate_need_migration();
215 test6_significant_insignificant_drop_aggregate_need_migration();
216 test7_move_closures_non_copy_types_might_need_migration();
217 test8_drop_order_and_blocks();
218 test9_drop_order_and_nested_closures();
219 test10_vec_of_significant_drop_type();