Skip to content

Commit 319f1ab

Browse files
committed
Tests for precise lint analysis
1 parent c01036a commit 319f1ab

File tree

3 files changed

+232
-0
lines changed

3 files changed

+232
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#![deny(disjoint_capture_drop_reorder)]
2+
//~^ NOTE: the lint level is defined here
3+
4+
#[derive(Debug)]
5+
struct Foo(i32);
6+
impl Drop for Foo {
7+
fn drop(&mut self) {
8+
println!("{:?} dropped", self.0);
9+
}
10+
}
11+
12+
struct ConstainsDropField(Foo, Foo);
13+
14+
#[derive(Debug)]
15+
struct ContainsAndImplsDrop(Foo);
16+
impl Drop for ContainsAndImplsDrop {
17+
fn drop(&mut self) {
18+
println!("{:?} dropped", self.0);
19+
}
20+
}
21+
22+
// Test that even if all paths starting at root variable that implement Drop are captured,
23+
// the lint is triggered if the root variable implements drop and isn't captured.
24+
fn test_precise_analysis_parent_root_impl_drop_not_captured() {
25+
let t = ContainsAndImplsDrop(Foo(10));
26+
27+
let c = || {
28+
//~^ERROR: drop order affected for closure because of `capture_disjoint_fields`
29+
//~| NOTE: drop(&(t));
30+
let _t = t.0;
31+
};
32+
33+
c();
34+
}
35+
36+
// Test that lint is triggered if a path that implements Drop is not captured by move
37+
fn test_precise_analysis_drop_paths_not_captured_by_move() {
38+
let t = ConstainsDropField(Foo(10), Foo(20));
39+
40+
let c = || {
41+
//~^ERROR: drop order affected for closure because of `capture_disjoint_fields`
42+
//~| NOTE: drop(&(t));
43+
let _t = t.0;
44+
let _t = &t.1;
45+
};
46+
47+
c();
48+
}
49+
50+
struct S;
51+
impl Drop for S {
52+
fn drop(&mut self) {
53+
}
54+
}
55+
56+
struct T(S, S);
57+
struct U(T, T);
58+
59+
// Test precise analysis for the lint works with paths longer than one.
60+
fn test_precise_analysis_long_path_missing() {
61+
let u = U(T(S, S), T(S, S));
62+
63+
let c = || {
64+
//~^ERROR: drop order affected for closure because of `capture_disjoint_fields`
65+
//~| NOTE: drop(&(u));
66+
let _x = u.0.0;
67+
let _x = u.0.1;
68+
let _x = u.1.0;
69+
};
70+
71+
c();
72+
}
73+
74+
fn main() {
75+
test_precise_analysis_parent_root_impl_drop_not_captured();
76+
test_precise_analysis_drop_paths_not_captured_by_move();
77+
test_precise_analysis_long_path_missing();
78+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
error: drop order affected for closure because of `capture_disjoint_fields`
2+
--> $DIR/precise.rs:27:13
3+
|
4+
LL | let c = || {
5+
| _____________^
6+
LL | |
7+
LL | |
8+
LL | | let _t = t.0;
9+
LL | | };
10+
| |_____^
11+
|
12+
note: the lint level is defined here
13+
--> $DIR/precise.rs:1:9
14+
|
15+
LL | #![deny(disjoint_capture_drop_reorder)]
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
= note: drop(&(t));
18+
19+
error: drop order affected for closure because of `capture_disjoint_fields`
20+
--> $DIR/precise.rs:40:13
21+
|
22+
LL | let c = || {
23+
| _____________^
24+
LL | |
25+
LL | |
26+
LL | | let _t = t.0;
27+
LL | | let _t = &t.1;
28+
LL | | };
29+
| |_____^
30+
|
31+
= note: drop(&(t));
32+
33+
error: drop order affected for closure because of `capture_disjoint_fields`
34+
--> $DIR/precise.rs:63:13
35+
|
36+
LL | let c = || {
37+
| _____________^
38+
LL | |
39+
LL | |
40+
LL | | let _x = u.0.0;
41+
LL | | let _x = u.0.1;
42+
LL | | let _x = u.1.0;
43+
LL | | };
44+
| |_____^
45+
|
46+
= note: drop(&(u));
47+
48+
error: aborting due to 3 previous errors
49+
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// run-pass
2+
3+
#![deny(disjoint_capture_drop_reorder)]
4+
5+
#[derive(Debug)]
6+
struct Foo(i32);
7+
impl Drop for Foo {
8+
fn drop(&mut self) {
9+
println!("{:?} dropped", self.0);
10+
}
11+
}
12+
13+
struct ConstainsDropField(Foo, Foo);
14+
15+
// Test that if all paths starting at root variable that implement Drop are captured
16+
// then it doesn't trigger the lint.
17+
fn test_precise_analysis_simple_1() {
18+
let t = (Foo(10), Foo(20), Foo(30));
19+
20+
let c = || {
21+
let _t = t.0;
22+
let _t = t.1;
23+
let _t = t.2;
24+
};
25+
26+
c();
27+
}
28+
29+
// Test that if all paths starting at root variable that implement Drop are captured
30+
// then it doesn't trigger the lint.
31+
fn test_precise_analysis_simple_2() {
32+
let t = ConstainsDropField(Foo(10), Foo(20));
33+
34+
let c = || {
35+
let _t = t.0;
36+
let _t = t.1;
37+
};
38+
39+
c();
40+
}
41+
42+
#[derive(Debug)]
43+
struct ContainsAndImplsDrop(Foo);
44+
impl Drop for ContainsAndImplsDrop {
45+
fn drop(&mut self) {
46+
println!("{:?} dropped", self.0);
47+
}
48+
}
49+
50+
// If a path isn't directly captured but requires Drop, then this tests that migrations aren't
51+
// needed if the a parent to that path is captured.
52+
fn test_precise_analysis_parent_captured_1() {
53+
let t = ConstainsDropField(Foo(10), Foo(20));
54+
55+
let c = || {
56+
let _t = t;
57+
};
58+
59+
c();
60+
}
61+
62+
// If a path isn't directly captured but requires Drop, then this tests that migrations aren't
63+
// needed if the a parent to that path is captured.
64+
fn test_precise_analysis_parent_captured_2() {
65+
let t = ContainsAndImplsDrop(Foo(10));
66+
67+
let c = || {
68+
let _t = t;
69+
};
70+
71+
c();
72+
}
73+
74+
struct S;
75+
impl Drop for S {
76+
fn drop(&mut self) {
77+
}
78+
}
79+
80+
struct T(S, S);
81+
struct U(T, T);
82+
83+
// Test that if the path is longer than just one element, precise analysis works correctly.
84+
fn test_precise_analysis_long_path() {
85+
let u = U(T(S, S), T(S, S));
86+
87+
let c = || {
88+
let _x = u.0.0;
89+
let _x = u.0.1;
90+
let _x = u.1.0;
91+
let _x = u.1.1;
92+
};
93+
94+
c();
95+
}
96+
97+
fn main() {
98+
test_precise_analysis_simple_1();
99+
test_precise_analysis_simple_2();
100+
101+
test_precise_analysis_parent_captured_1();
102+
test_precise_analysis_parent_captured_2();
103+
104+
test_precise_analysis_long_path();
105+
}

0 commit comments

Comments
 (0)