|
| 1 | +// run-pass |
1 | 2 | // run-rustfix |
2 | 3 |
|
3 | 4 | #![deny(rust_2021_incompatible_closure_captures)] |
4 | | -//~^ NOTE: the lint level is defined here |
| 5 | +#![allow(unused)] |
5 | 6 |
|
6 | | -// Test cases for types that implement an insignificant drop (stlib defined) |
7 | | - |
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()); |
14 | | - |
15 | | - let c = || { |
16 | | - let _ = (&t, &t1, &t2); |
17 | | - //~^ ERROR: drop order |
18 | | - //~| NOTE: for more information, see |
19 | | - //~| HELP: add a dummy let to cause `t`, `t1`, `t2` to be fully captured |
20 | | - |
21 | | - let _t = t.0; |
22 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0` |
23 | | - let _t1 = t1.0; |
24 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0` |
25 | | - let _t2 = t2.0; |
26 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t2`, but in Rust 2021, it will only capture `t2.0` |
27 | | - }; |
28 | | - |
29 | | - c(); |
30 | | -} |
31 | | -//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure |
32 | | -//~| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure |
33 | | -//~| in Rust 2018, `t2` is dropped here, but in Rust 2021, only `t2.0` will be dropped here as part of the closure |
34 | | - |
35 | | -// String implements drop and therefore should be migrated. |
36 | | -// But in this test cases, `t2` is completely captured and when it is dropped won't be affected |
37 | | -fn test2_only_precise_paths_need_migration() { |
38 | | - let t = (String::new(), String::new()); |
39 | | - let t1 = (String::new(), String::new()); |
40 | | - let t2 = (String::new(), String::new()); |
41 | | - |
42 | | - let c = || { |
43 | | - let _ = (&t, &t1); |
44 | | - //~^ ERROR: drop order |
45 | | - //~| NOTE: for more information, see |
46 | | - //~| HELP: add a dummy let to cause `t`, `t1` to be fully captured |
47 | | - let _t = t.0; |
48 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0` |
49 | | - let _t1 = t1.0; |
50 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.0` |
51 | | - let _t2 = t2; |
52 | | - }; |
53 | | - |
54 | | - c(); |
55 | | -} |
56 | | -//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure |
57 | | -//~| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure |
58 | | - |
59 | | -// If a variable would've not been captured by value then it would've not been |
60 | | -// dropped with the closure and therefore doesn't need migration. |
61 | | -fn test3_only_by_value_need_migration() { |
62 | | - let t = (String::new(), String::new()); |
63 | | - let t1 = (String::new(), String::new()); |
64 | | - let c = || { |
65 | | - let _ = &t; |
66 | | - //~^ ERROR: drop order |
67 | | - //~| NOTE: for more information, see |
68 | | - //~| HELP: add a dummy let to cause `t` to be fully captured |
69 | | - let _t = t.0; |
70 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0` |
71 | | - println!("{}", t1.1); |
72 | | - }; |
73 | | - |
74 | | - c(); |
75 | | -} |
76 | | -//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure |
77 | | - |
78 | | -// Copy types get copied into the closure instead of move. Therefore we don't need to |
79 | | -// migrate then as their drop order isn't tied to the closure. |
80 | | -fn test4_only_non_copy_types_need_migration() { |
81 | | - let t = (String::new(), String::new()); |
| 7 | +#![feature(once_cell)] |
82 | 8 |
|
83 | | - // `t1` is Copy because all of its elements are Copy |
84 | | - let t1 = (0i32, 0i32); |
85 | | - |
86 | | - let c = || { |
87 | | - let _ = &t; |
88 | | - //~^ ERROR: drop order |
89 | | - //~| NOTE: for more information, see |
90 | | - //~| HELP: add a dummy let to cause `t` to be fully captured |
91 | | - let _t = t.0; |
92 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0` |
93 | | - let _t1 = t1.0; |
94 | | - }; |
95 | | - |
96 | | - c(); |
97 | | -} |
98 | | -//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure |
99 | | - |
100 | | -fn test5_only_drop_types_need_migration() { |
101 | | - struct S(i32, i32); |
102 | | - |
103 | | - let t = (String::new(), String::new()); |
104 | | - |
105 | | - // `s` doesn't implement Drop or any elements within it, and doesn't need migration |
106 | | - let s = S(0i32, 0i32); |
107 | | - |
108 | | - let c = || { |
109 | | - let _ = &t; |
110 | | - //~^ ERROR: drop order |
111 | | - //~| NOTE: for more information, see |
112 | | - //~| HELP: add a dummy let to cause `t` to be fully captured |
113 | | - let _t = t.0; |
114 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0` |
115 | | - let _s = s.0; |
116 | | - }; |
117 | | - |
118 | | - c(); |
119 | | -} |
120 | | -//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure |
121 | | - |
122 | | -// Since we are using a move closure here, both `t` and `t1` get moved |
123 | | -// even though they are being used by ref inside the closure. |
124 | | -fn test6_move_closures_non_copy_types_might_need_migration() { |
125 | | - let t = (String::new(), String::new()); |
126 | | - let t1 = (String::new(), String::new()); |
127 | | - let c = move || { |
128 | | - let _ = (&t1, &t); |
129 | | - //~^ ERROR: drop order |
130 | | - //~| NOTE: for more information, see |
131 | | - //~| HELP: add a dummy let to cause `t1`, `t` to be fully captured |
132 | | - println!("{} {}", t1.1, t.1); |
133 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.1` |
134 | | - //~| NOTE: in Rust 2018, this closure captures all of `t1`, but in Rust 2021, it will only capture `t1.1` |
135 | | - }; |
| 9 | +// Test cases for types that implement an insignificant drop (stlib defined) |
136 | 10 |
|
137 | | - c(); |
138 | | -} |
139 | | -//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure |
140 | | -//~| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.1` will be dropped here as part of the closure |
| 11 | +macro_rules! test_insig_dtor_for_type { |
| 12 | + ($t: ty, $disambiguator: ident) => { |
| 13 | + mod $disambiguator { |
| 14 | + use std::collections::*; |
| 15 | + use std::lazy::SyncOnceCell; |
| 16 | + use std::rc::Rc; |
| 17 | + use std::sync::Mutex; |
141 | 18 |
|
142 | | -// Test migration analysis in case of Drop + Non Drop aggregates. |
143 | | -// Note we need migration here only because the non-copy (because Drop type) is captured, |
144 | | -// otherwise we won't need to, since we can get away with just by ref capture in that case. |
145 | | -fn test7_drop_non_drop_aggregate_need_migration() { |
146 | | - let t = (String::new(), String::new(), 0i32); |
| 19 | + fn _test_for_type(t: $t) { |
| 20 | + let tup = (Mutex::new(0), t); |
147 | 21 |
|
148 | | - let c = || { |
149 | | - let _ = &t; |
150 | | - //~^ ERROR: drop order |
151 | | - //~| NOTE: for more information, see |
152 | | - //~| HELP: add a dummy let to cause `t` to be fully captured |
153 | | - let _t = t.0; |
154 | | - //~^ NOTE: in Rust 2018, this closure captures all of `t`, but in Rust 2021, it will only capture `t.0` |
| 22 | + let _c = || tup.0; |
| 23 | + } |
| 24 | + } |
155 | 25 | }; |
156 | | - |
157 | | - c(); |
158 | 26 | } |
159 | | -//~^ in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure |
160 | 27 |
|
161 | | -fn main() { |
162 | | - test1_all_need_migration(); |
163 | | - test2_only_precise_paths_need_migration(); |
164 | | - test3_only_by_value_need_migration(); |
165 | | - test4_only_non_copy_types_need_migration(); |
166 | | - test5_only_drop_types_need_migration(); |
167 | | - test6_move_closures_non_copy_types_might_need_migration(); |
168 | | - test7_drop_non_drop_aggregate_need_migration(); |
169 | | -} |
| 28 | +test_insig_dtor_for_type!(i32, prim_i32); |
| 29 | +test_insig_dtor_for_type!(Vec<i32>, vec_i32); |
| 30 | +test_insig_dtor_for_type!(String, string); |
| 31 | +test_insig_dtor_for_type!(Vec<String>, vec_string); |
| 32 | +//test_insig_dtor_for_type!(HashMap<String, String>, hash_map); |
| 33 | +test_insig_dtor_for_type!(BTreeMap<String, i32>, btree_map); |
| 34 | +test_insig_dtor_for_type!(LinkedList<String>, linked_list); |
| 35 | +test_insig_dtor_for_type!(Rc<i32>, rc_i32); |
| 36 | +test_insig_dtor_for_type!(Rc<String>, rc_string); |
| 37 | +test_insig_dtor_for_type!(SyncOnceCell<String>, onecell); |
| 38 | +test_insig_dtor_for_type!(std::vec::IntoIter<String>, vec_into_iter); |
| 39 | +test_insig_dtor_for_type!(btree_map::IntoIter<String, String>, btree_map_into_iter); |
| 40 | +test_insig_dtor_for_type!(std::array::IntoIter<String, 5>, array_into_iter); |
| 41 | + |
| 42 | +fn main() {} |
0 commit comments