3 #![deny(rust_2021_incompatible_closure_captures)]
4 //~^ NOTE: the lint level is defined here
6 // Test cases for types that implement a insignificant drop (stlib defined)
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());
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
21 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
23 //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
25 //~^ NOTE: in Rust 2018, closure captures all of `t2`, but in Rust 2021, it only captures `t2.0`
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
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());
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
46 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
48 //~^ NOTE: in Rust 2018, closure captures all of `t1`, but in Rust 2021, it only captures `t1.0`
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
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
67 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
73 //~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
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());
80 // `t1` is Copy because all of its elements are Copy
81 let t1 = (0i32, 0i32);
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
88 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
94 //~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
96 fn test5_only_drop_types_need_migration() {
99 let t = (String::new(), String::new());
101 // `s` doesn't implement Drop or any elements within it, and doesn't need migration
102 let s = S(0i32, 0i32);
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
109 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
115 //~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
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`
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
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);
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
147 //~^ NOTE: in Rust 2018, closure captures all of `t`, but in Rust 2021, it only captures `t.0`
152 //~^ in Rust 2018, `t` would be dropped here, but in Rust 2021, only `t.0` would be dropped here alongside the closure
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();