|
| 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