Skip to content

Commit d30a5bf

Browse files
committed
Tests for 2229 lint
1 parent 36352d2 commit d30a5bf

File tree

5 files changed

+559
-0
lines changed

5 files changed

+559
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#![deny(disjoint_capture_drop_reorder)]
2+
//~^ NOTE: the lint level is defined here
3+
4+
// Test cases for types that implement a insignificant drop (stlib defined)
5+
6+
// `t` needs Drop because one of its elements needs drop,
7+
// therefore precise capture might affect drop ordering
8+
fn test1_all_need_migration() {
9+
let t = (String::new(), String::new());
10+
let t1 = (String::new(), String::new());
11+
let t2 = (String::new(), String::new());
12+
13+
let c = || {
14+
//~^ERROR: Drop order affected for closure because of `capture_disjoint_fields`
15+
//~| NOTE: let (t, t1, t2) = (t, t1, t2);
16+
let _t = t.0;
17+
let _t1 = t1.0;
18+
let _t2 = t2.0;
19+
};
20+
21+
c();
22+
}
23+
24+
// String implements drop and therefore should be migrated.
25+
// But in this test cases, `t2` is completely captured and when it is dropped won't be affected
26+
fn test2_only_precise_paths_need_migration() {
27+
let t = (String::new(), String::new());
28+
let t1 = (String::new(), String::new());
29+
let t2 = (String::new(), String::new());
30+
31+
let c = || {
32+
//~^ERROR: Drop order affected for closure because of `capture_disjoint_fields`
33+
//~| NOTE: let (t, t1) = (t, t1);
34+
let _t = t.0;
35+
let _t1 = t1.0;
36+
let _t2 = t2;
37+
};
38+
39+
c();
40+
}
41+
42+
// If a variable would've not been captured by value then it would've not been
43+
// dropped with the closure and therefore doesn't need migration.
44+
fn test3_only_by_value_need_migration() {
45+
let t = (String::new(), String::new());
46+
let t1 = (String::new(), String::new());
47+
let c = || {
48+
//~^ERROR: Drop order affected for closure because of `capture_disjoint_fields`
49+
//~| NOTE: let (t) = (t);
50+
let _t = t.0;
51+
println!("{}", t1.1);
52+
};
53+
54+
c();
55+
}
56+
57+
// Copy types get copied into the closure instead of move. Therefore we don't need to
58+
// migrate then as their drop order isn't tied to the closure.
59+
fn test4_only_non_copy_types_need_migration() {
60+
let t = (String::new(), String::new());
61+
62+
// `t1` is Copy because all of its elements are Copy
63+
let t1 = (0i32, 0i32);
64+
65+
let c = || {
66+
//~^ERROR: Drop order affected for closure because of `capture_disjoint_fields`
67+
//~| NOTE: let (t) = (t);
68+
let _t = t.0;
69+
let _t1 = t1.0;
70+
};
71+
72+
c();
73+
}
74+
75+
fn test5_only_drop_types_need_migration() {
76+
struct S(i32, i32);
77+
78+
let t = (String::new(), String::new());
79+
80+
// `s` doesn't implement Drop or any elements within it, and doesn't need migration
81+
let s = S(0i32, 0i32);
82+
83+
let c = || {
84+
//~^ERROR: Drop order affected for closure because of `capture_disjoint_fields`
85+
//~| NOTE: let (t) = (t);
86+
let _t = t.0;
87+
let _s = s.0;
88+
};
89+
90+
c();
91+
}
92+
93+
// Since we are using a move closure here, both `t` and `t1` get moved
94+
// even though they are being used by ref inside the closure.
95+
fn test6_move_closures_non_copy_types_might_need_migration() {
96+
let t = (String::new(), String::new());
97+
let t1 = (String::new(), String::new());
98+
let c = move || {
99+
//~^ERROR: Drop order affected for closure because of `capture_disjoint_fields`
100+
//~| NOTE: let (t1, t) = (t1, t);
101+
println!("{} {}", t1.1, t.1);
102+
};
103+
104+
c();
105+
}
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 test7_drop_non_drop_aggregate_need_migration() {
111+
let t = (String::new(), 0i32);
112+
113+
let c = || {
114+
//~^ERROR: Drop order affected for closure because of `capture_disjoint_fields`
115+
//~| NOTE: let (t) = (t);
116+
let _t = t.0;
117+
};
118+
119+
c();
120+
}
121+
122+
fn main() {
123+
test1_all_need_migration();
124+
test2_only_precise_paths_need_migration();
125+
test3_only_by_value_need_migration();
126+
test4_only_non_copy_types_need_migration();
127+
test5_only_drop_types_need_migration();
128+
test6_move_closures_non_copy_types_might_need_migration();
129+
test7_drop_non_drop_aggregate_need_migration();
130+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
error: Drop order affected for closure because of `capture_disjoint_fields`
2+
--> $DIR/insignificant_drop.rs:13:13
3+
|
4+
LL | let c = || {
5+
| _____________^
6+
LL | |
7+
LL | |
8+
LL | | let _t = t.0;
9+
LL | | let _t1 = t1.0;
10+
LL | | let _t2 = t2.0;
11+
LL | | };
12+
| |_____^
13+
|
14+
note: the lint level is defined here
15+
--> $DIR/insignificant_drop.rs:1:9
16+
|
17+
LL | #![deny(disjoint_capture_drop_reorder)]
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
19+
= note: let (t, t1, t2) = (t, t1, t2);
20+
21+
error: Drop order affected for closure because of `capture_disjoint_fields`
22+
--> $DIR/insignificant_drop.rs:31:13
23+
|
24+
LL | let c = || {
25+
| _____________^
26+
LL | |
27+
LL | |
28+
LL | | let _t = t.0;
29+
LL | | let _t1 = t1.0;
30+
LL | | let _t2 = t2;
31+
LL | | };
32+
| |_____^
33+
|
34+
= note: let (t, t1) = (t, t1);
35+
36+
error: Drop order affected for closure because of `capture_disjoint_fields`
37+
--> $DIR/insignificant_drop.rs:47:13
38+
|
39+
LL | let c = || {
40+
| _____________^
41+
LL | |
42+
LL | |
43+
LL | | let _t = t.0;
44+
LL | | println!("{}", t1.1);
45+
LL | | };
46+
| |_____^
47+
|
48+
= note: let (t) = (t);
49+
50+
error: Drop order affected for closure because of `capture_disjoint_fields`
51+
--> $DIR/insignificant_drop.rs:65:13
52+
|
53+
LL | let c = || {
54+
| _____________^
55+
LL | |
56+
LL | |
57+
LL | | let _t = t.0;
58+
LL | | let _t1 = t1.0;
59+
LL | | };
60+
| |_____^
61+
|
62+
= note: let (t) = (t);
63+
64+
error: Drop order affected for closure because of `capture_disjoint_fields`
65+
--> $DIR/insignificant_drop.rs:83:13
66+
|
67+
LL | let c = || {
68+
| _____________^
69+
LL | |
70+
LL | |
71+
LL | | let _t = t.0;
72+
LL | | let _s = s.0;
73+
LL | | };
74+
| |_____^
75+
|
76+
= note: let (t) = (t);
77+
78+
error: Drop order affected for closure because of `capture_disjoint_fields`
79+
--> $DIR/insignificant_drop.rs:98:13
80+
|
81+
LL | let c = move || {
82+
| _____________^
83+
LL | |
84+
LL | |
85+
LL | | println!("{} {}", t1.1, t.1);
86+
LL | | };
87+
| |_____^
88+
|
89+
= note: let (t1, t) = (t1, t);
90+
91+
error: Drop order affected for closure because of `capture_disjoint_fields`
92+
--> $DIR/insignificant_drop.rs:113:13
93+
|
94+
LL | let c = || {
95+
| _____________^
96+
LL | |
97+
LL | |
98+
LL | | let _t = t.0;
99+
LL | | };
100+
| |_____^
101+
|
102+
= note: let (t) = (t);
103+
104+
error: aborting due to 7 previous errors
105+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// run-pass
2+
3+
// Set of test cases that don't need migrations
4+
5+
#![deny(disjoint_capture_drop_reorder)]
6+
7+
8+
// Copy types as copied by the closure instead of being moved into the closure
9+
// Therefore their drop order isn't tied to the closure and won't be requiring any
10+
// migrations.
11+
fn test1_only_copy_types() {
12+
let t = (0i32, 0i32);
13+
14+
let c = || {
15+
let _t = t.0;
16+
};
17+
18+
c();
19+
}
20+
21+
// Same as test1 but using a move closure
22+
fn test2_only_copy_types_move_closure() {
23+
let t = (0i32, 0i32);
24+
25+
let c = move || {
26+
println!("{}", t.0);
27+
};
28+
29+
c();
30+
}
31+
32+
// Don't need to migrate if captured by ref
33+
fn test3_only_copy_types_move_closure() {
34+
let t = (String::new(), String::new());
35+
36+
let c = || {
37+
println!("{}", t.0);
38+
};
39+
40+
c();
41+
}
42+
43+
// Test migration analysis in case of Insignificant Drop + Non Drop aggregates.
44+
// Note in this test the closure captures a non Drop type and therefore the variable
45+
// is only captured by ref.
46+
fn test4_insignificant_drop_non_drop_aggregate() {
47+
let t = (String::new(), 0i32);
48+
49+
let c = || {
50+
let _t = t.1;
51+
};
52+
53+
c();
54+
}
55+
56+
57+
struct Foo(i32);
58+
impl Drop for Foo {
59+
fn drop(&mut self) {
60+
println!("{:?} dropped", self.0);
61+
}
62+
}
63+
64+
// Test migration analysis in case of Significant Drop + Non Drop aggregates.
65+
// Note in this test the closure captures a non Drop type and therefore the variable
66+
// is only captured by ref.
67+
fn test5_significant_drop_non_drop_aggregate() {
68+
let t = (Foo(0), 0i32);
69+
70+
let c = || {
71+
let _t = t.1;
72+
};
73+
74+
c();
75+
}
76+
77+
fn main() {
78+
test1_only_copy_types();
79+
test2_only_copy_types_move_closure();
80+
test3_only_copy_types_move_closure();
81+
test4_insignificant_drop_non_drop_aggregate();
82+
test5_significant_drop_non_drop_aggregate();
83+
84+
}

0 commit comments

Comments
 (0)