Skip to content

Commit 0897db5

Browse files
committed
Test for restricting capture precision
1 parent 1373f98 commit 0897db5

File tree

12 files changed

+657
-0
lines changed

12 files changed

+657
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Test that we handle derferences properly when only some of the captures are being moved with
2+
// `capture_disjoint_fields` enabled.
3+
4+
5+
#![feature(capture_disjoint_fields)]
6+
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
7+
//~| NOTE: `#[warn(incomplete_features)]` on by default
8+
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
9+
#![feature(rustc_attrs)]
10+
11+
#[derive(Debug, Default)]
12+
struct SomeLargeType;
13+
struct MuchLargerType([SomeLargeType; 32]);
14+
15+
// Ensure that we don't capture any derefs when moving captures into the closures,
16+
// i.e. only data from the enclosing stack is moved.
17+
fn big_box() {
18+
let s = MuchLargerType(Default::default());
19+
let b = Box::new(s);
20+
let t = (b, 10);
21+
22+
let c = #[rustc_capture_analysis]
23+
//~^ ERROR: attributes on expressions are experimental
24+
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
25+
|| {
26+
//~^ First Pass analysis includes:
27+
//~| Min Capture analysis includes:
28+
let p = t.0.0;
29+
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
30+
//~| NOTE: Min Capture t[(0, 0)] -> ByValue
31+
println!("{} {:?}", t.1, p);
32+
//~^ NOTE: Capturing t[(1, 0)] -> ImmBorrow
33+
//~| NOTE: Min Capture t[(1, 0)] -> ImmBorrow
34+
};
35+
36+
c();
37+
}
38+
39+
fn main() {
40+
big_box();
41+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
error[E0658]: attributes on expressions are experimental
2+
--> $DIR/by_value.rs:22:13
3+
|
4+
LL | let c = #[rustc_capture_analysis]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
8+
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
9+
10+
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
11+
--> $DIR/by_value.rs:5:12
12+
|
13+
LL | #![feature(capture_disjoint_fields)]
14+
| ^^^^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: `#[warn(incomplete_features)]` on by default
17+
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
18+
19+
error: First Pass analysis includes:
20+
--> $DIR/by_value.rs:25:5
21+
|
22+
LL | / || {
23+
LL | |
24+
LL | |
25+
LL | | let p = t.0.0;
26+
... |
27+
LL | |
28+
LL | | };
29+
| |_____^
30+
|
31+
note: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
32+
--> $DIR/by_value.rs:28:17
33+
|
34+
LL | let p = t.0.0;
35+
| ^^^^^
36+
note: Capturing t[(1, 0)] -> ImmBorrow
37+
--> $DIR/by_value.rs:31:29
38+
|
39+
LL | println!("{} {:?}", t.1, p);
40+
| ^^^
41+
42+
error: Min Capture analysis includes:
43+
--> $DIR/by_value.rs:25:5
44+
|
45+
LL | / || {
46+
LL | |
47+
LL | |
48+
LL | | let p = t.0.0;
49+
... |
50+
LL | |
51+
LL | | };
52+
| |_____^
53+
|
54+
note: Min Capture t[(0, 0)] -> ByValue
55+
--> $DIR/by_value.rs:28:17
56+
|
57+
LL | let p = t.0.0;
58+
| ^^^^^
59+
note: Min Capture t[(1, 0)] -> ImmBorrow
60+
--> $DIR/by_value.rs:31:29
61+
|
62+
LL | println!("{} {:?}", t.1, p);
63+
| ^^^
64+
65+
error: aborting due to 3 previous errors; 1 warning emitted
66+
67+
For more information about this error, try `rustc --explain E0658`.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Test that move closures drop derefs with `capture_disjoint_fields` enabled.
2+
3+
#![feature(capture_disjoint_fields)]
4+
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
5+
//~| NOTE: `#[warn(incomplete_features)]` on by default
6+
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
7+
#![feature(rustc_attrs)]
8+
9+
// Test we truncate derefs properly
10+
fn simple_ref() {
11+
let mut s = 10;
12+
let ref_s = &mut s;
13+
14+
let mut c = #[rustc_capture_analysis]
15+
//~^ ERROR: attributes on expressions are experimental
16+
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
17+
move || {
18+
//~^ ERROR: First Pass analysis includes:
19+
//~| ERROR: Min Capture analysis includes:
20+
*ref_s += 10;
21+
//~^ NOTE: Capturing ref_s[Deref] -> ByValue
22+
//~| NOTE: Min Capture ref_s[] -> ByValue
23+
};
24+
c();
25+
}
26+
27+
// Test we truncate derefs properly
28+
fn struct_contains_ref_to_another_struct() {
29+
struct S(String);
30+
struct T<'a>(&'a mut S);
31+
32+
let mut s = S("s".into());
33+
let t = T(&mut s);
34+
35+
let mut c = #[rustc_capture_analysis]
36+
//~^ ERROR: attributes on expressions are experimental
37+
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
38+
move || {
39+
//~^ ERROR: First Pass analysis includes:
40+
//~| ERROR: Min Capture analysis includes:
41+
t.0.0 = "new s".into();
42+
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
43+
//~| NOTE: Min Capture t[(0, 0)] -> ByValue
44+
};
45+
46+
c();
47+
}
48+
49+
// Test that we don't reduce precision when there is nothing deref.
50+
fn no_ref() {
51+
struct S(String);
52+
struct T(S);
53+
54+
let t = T(S("s".into()));
55+
let mut c = #[rustc_capture_analysis]
56+
//~^ ERROR: attributes on expressions are experimental
57+
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
58+
move || {
59+
//~^ ERROR: First Pass analysis includes:
60+
//~| ERROR: Min Capture analysis includes:
61+
t.0.0 = "new S".into();
62+
//~^ NOTE: Capturing t[(0, 0),(0, 0)] -> ByValue
63+
//~| NOTE: Min Capture t[(0, 0),(0, 0)] -> ByValue
64+
};
65+
c();
66+
}
67+
68+
fn main() {
69+
simple_ref();
70+
struct_contains_ref_to_another_struct();
71+
no_ref();
72+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
error[E0658]: attributes on expressions are experimental
2+
--> $DIR/move_closure.rs:14:17
3+
|
4+
LL | let mut c = #[rustc_capture_analysis]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
8+
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
9+
10+
error[E0658]: attributes on expressions are experimental
11+
--> $DIR/move_closure.rs:35:17
12+
|
13+
LL | let mut c = #[rustc_capture_analysis]
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
17+
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
18+
19+
error[E0658]: attributes on expressions are experimental
20+
--> $DIR/move_closure.rs:55:17
21+
|
22+
LL | let mut c = #[rustc_capture_analysis]
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
24+
|
25+
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
26+
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
27+
28+
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
29+
--> $DIR/move_closure.rs:3:12
30+
|
31+
LL | #![feature(capture_disjoint_fields)]
32+
| ^^^^^^^^^^^^^^^^^^^^^^^
33+
|
34+
= note: `#[warn(incomplete_features)]` on by default
35+
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
36+
37+
error: First Pass analysis includes:
38+
--> $DIR/move_closure.rs:17:5
39+
|
40+
LL | / move || {
41+
LL | |
42+
LL | |
43+
LL | | *ref_s += 10;
44+
LL | |
45+
LL | |
46+
LL | | };
47+
| |_____^
48+
|
49+
note: Capturing ref_s[Deref] -> ByValue
50+
--> $DIR/move_closure.rs:20:9
51+
|
52+
LL | *ref_s += 10;
53+
| ^^^^^^
54+
55+
error: Min Capture analysis includes:
56+
--> $DIR/move_closure.rs:17:5
57+
|
58+
LL | / move || {
59+
LL | |
60+
LL | |
61+
LL | | *ref_s += 10;
62+
LL | |
63+
LL | |
64+
LL | | };
65+
| |_____^
66+
|
67+
note: Min Capture ref_s[] -> ByValue
68+
--> $DIR/move_closure.rs:20:9
69+
|
70+
LL | *ref_s += 10;
71+
| ^^^^^^
72+
73+
error: First Pass analysis includes:
74+
--> $DIR/move_closure.rs:38:5
75+
|
76+
LL | / move || {
77+
LL | |
78+
LL | |
79+
LL | | t.0.0 = "new s".into();
80+
LL | |
81+
LL | |
82+
LL | | };
83+
| |_____^
84+
|
85+
note: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
86+
--> $DIR/move_closure.rs:41:9
87+
|
88+
LL | t.0.0 = "new s".into();
89+
| ^^^^^
90+
91+
error: Min Capture analysis includes:
92+
--> $DIR/move_closure.rs:38:5
93+
|
94+
LL | / move || {
95+
LL | |
96+
LL | |
97+
LL | | t.0.0 = "new s".into();
98+
LL | |
99+
LL | |
100+
LL | | };
101+
| |_____^
102+
|
103+
note: Min Capture t[(0, 0)] -> ByValue
104+
--> $DIR/move_closure.rs:41:9
105+
|
106+
LL | t.0.0 = "new s".into();
107+
| ^^^^^
108+
109+
error: First Pass analysis includes:
110+
--> $DIR/move_closure.rs:58:5
111+
|
112+
LL | / move || {
113+
LL | |
114+
LL | |
115+
LL | | t.0.0 = "new S".into();
116+
LL | |
117+
LL | |
118+
LL | | };
119+
| |_____^
120+
|
121+
note: Capturing t[(0, 0),(0, 0)] -> ByValue
122+
--> $DIR/move_closure.rs:61:9
123+
|
124+
LL | t.0.0 = "new S".into();
125+
| ^^^^^
126+
127+
error: Min Capture analysis includes:
128+
--> $DIR/move_closure.rs:58:5
129+
|
130+
LL | / move || {
131+
LL | |
132+
LL | |
133+
LL | | t.0.0 = "new S".into();
134+
LL | |
135+
LL | |
136+
LL | | };
137+
| |_____^
138+
|
139+
note: Min Capture t[(0, 0),(0, 0)] -> ByValue
140+
--> $DIR/move_closure.rs:61:9
141+
|
142+
LL | t.0.0 = "new S".into();
143+
| ^^^^^
144+
145+
error: aborting due to 9 previous errors; 1 warning emitted
146+
147+
For more information about this error, try `rustc --explain E0658`.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// run-pass
2+
3+
// Test that ByValue captures compile sucessefully especially when the captures are
4+
// derefenced within the closure.
5+
6+
#![feature(capture_disjoint_fields)]
7+
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
8+
9+
#[derive(Debug, Default)]
10+
struct SomeLargeType;
11+
struct MuchLargerType([SomeLargeType; 32]);
12+
13+
fn big_box() {
14+
let s = MuchLargerType(Default::default());
15+
let b = Box::new(s);
16+
let t = (b, 10);
17+
18+
let c = || {
19+
let p = t.0.0;
20+
println!("{} {:?}", t.1, p);
21+
};
22+
23+
c();
24+
}
25+
26+
fn main() {
27+
big_box();
28+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/by_value.rs:6:12
3+
|
4+
LL | #![feature(capture_disjoint_fields)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
9+
10+
warning: 1 warning emitted
11+

0 commit comments

Comments
 (0)