Skip to content

Commit 3aaf6e9

Browse files
Add initial set of testcases for RFC 2229
Co-authored-by: Dhruv Jauhar <[email protected]>
1 parent 916549e commit 3aaf6e9

34 files changed

+914
-2
lines changed

compiler/rustc_typeck/src/check/upvar.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
169169
)
170170
.consume_body(body);
171171

172+
log_capture_analysis!(
173+
self,
174+
closure_def_id,
175+
"capture information: {:#?}",
176+
delegate.capture_information
177+
);
178+
172179
if let Some(closure_substs) = infer_kind {
173180
// Unify the (as yet unbound) type variable in the closure
174181
// substs with the kind we inferred.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(capture_disjoint_fields)]
2+
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
3+
#![feature(rustc_attrs)]
4+
5+
// Ensure that capture analysis results in arrays being completely captured.
6+
fn main() {
7+
let mut m = [1, 2, 3, 4, 5];
8+
9+
let mut c = #[rustc_capture_analysis]
10+
//~^ ERROR: attributes on expressions are experimental
11+
|| {
12+
m[0] += 10;
13+
m[1] += 40;
14+
};
15+
16+
c();
17+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0658]: attributes on expressions are experimental
2+
--> $DIR/arrays-completely-captured.rs:9: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+
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
11+
--> $DIR/arrays-completely-captured.rs:1: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: aborting due to previous error; 1 warning emitted
20+
21+
For more information about this error, try `rustc --explain E0658`.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
For closure=DefId(0:4 ~ arrays_completely_captured[317d]::main::{closure#0}): Using new-style capture analysis
2+
For closure=DefId(0:4 ~ arrays_completely_captured[317d]::main::{closure#0}): capture information: {
3+
Place {
4+
base_ty: [i32; 5],
5+
base: Upvar(
6+
UpvarId(HirId { owner: DefId(0:3 ~ arrays_completely_captured[317d]::main), local_id: 1 };`m`;DefId(0:4 ~ arrays_completely_captured[317d]::main::{closure#0})),
7+
),
8+
projections: [],
9+
}: CaptureInfo {
10+
expr_id: Some(
11+
HirId {
12+
owner: DefId(0:3 ~ arrays_completely_captured[317d]::main),
13+
local_id: 12,
14+
},
15+
),
16+
capture_kind: ByRef(
17+
UpvarBorrow(MutBorrow, '_#6r),
18+
),
19+
},
20+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// FIXME(arora-aman) add run-pass once 2229 is implemented
2+
3+
#![feature(capture_disjoint_fields)]
4+
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
5+
#![feature(rustc_attrs)]
6+
7+
struct Point {
8+
x: i32,
9+
y: i32,
10+
}
11+
12+
fn main() {
13+
let mut p = Point { x: 10, y: 10 };
14+
15+
let c = #[rustc_capture_analysis]
16+
//~^ ERROR: attributes on expressions are experimental
17+
|| {
18+
println!("{}", p.x);
19+
};
20+
21+
// `c` should only capture `p.x`, therefore mutating `p.y` is allowed.
22+
let py = &mut p.y;
23+
24+
c();
25+
*py = 20;
26+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0658]: attributes on expressions are experimental
2+
--> $DIR/capture-disjoint-field-struct.rs:15: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/capture-disjoint-field-struct.rs:3: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: aborting due to previous error; 1 warning emitted
20+
21+
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+
For closure=DefId(0:7 ~ capture_disjoint_field_struct[317d]::main::{closure#0}): Using new-style capture analysis
2+
For closure=DefId(0:7 ~ capture_disjoint_field_struct[317d]::main::{closure#0}): capture information: {
3+
Place {
4+
base_ty: Point,
5+
base: Upvar(
6+
UpvarId(HirId { owner: DefId(0:6 ~ capture_disjoint_field_struct[317d]::main), local_id: 1 };`p`;DefId(0:7 ~ capture_disjoint_field_struct[317d]::main::{closure#0})),
7+
),
8+
projections: [
9+
Projection {
10+
ty: i32,
11+
kind: Field(
12+
0,
13+
0,
14+
),
15+
},
16+
],
17+
}: CaptureInfo {
18+
expr_id: Some(
19+
HirId {
20+
owner: DefId(0:6 ~ capture_disjoint_field_struct[317d]::main),
21+
local_id: 31,
22+
},
23+
),
24+
capture_kind: ByRef(
25+
UpvarBorrow(ImmBorrow, '_#35r),
26+
),
27+
},
28+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// FIXME(arora-aman) add run-pass once 2229 is implemented
2+
3+
#![feature(capture_disjoint_fields)]
4+
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
5+
#![feature(rustc_attrs)]
6+
7+
fn main() {
8+
let mut t = (10, 10);
9+
10+
let c = #[rustc_capture_analysis]
11+
//~^ ERROR: attributes on expressions are experimental
12+
|| {
13+
println!("{}", t.0);
14+
};
15+
16+
// `c` only captures t.0, therefore mutating t.1 is allowed.
17+
let t1 = &mut t.1;
18+
19+
c();
20+
*t1 = 20;
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0658]: attributes on expressions are experimental
2+
--> $DIR/capture-disjoint-field-tuple.rs:8: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/capture-disjoint-field-tuple.rs:1: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: aborting due to previous error; 1 warning emitted
20+
21+
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+
For closure=DefId(0:4 ~ capture_disjoint_field_tuple[317d]::main::{closure#0}): Using new-style capture analysis
2+
For closure=DefId(0:4 ~ capture_disjoint_field_tuple[317d]::main::{closure#0}): capture information: {
3+
Place {
4+
base_ty: (i32, i32),
5+
base: Upvar(
6+
UpvarId(HirId { owner: DefId(0:3 ~ capture_disjoint_field_tuple[317d]::main), local_id: 1 };`t`;DefId(0:4 ~ capture_disjoint_field_tuple[317d]::main::{closure#0})),
7+
),
8+
projections: [
9+
Projection {
10+
ty: i32,
11+
kind: Field(
12+
0,
13+
0,
14+
),
15+
},
16+
],
17+
}: CaptureInfo {
18+
expr_id: Some(
19+
HirId {
20+
owner: DefId(0:3 ~ capture_disjoint_field_tuple[317d]::main),
21+
local_id: 28,
22+
},
23+
),
24+
capture_kind: ByRef(
25+
UpvarBorrow(ImmBorrow, '_#35r),
26+
),
27+
},
28+
}

src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
fn main() {
66
let s = format!("s");
77

8-
let c = #[rustc_capture_analysis] || {
8+
let c = #[rustc_capture_analysis]
99
//~^ ERROR: attributes on expressions are experimental
10+
|| {
1011
println!("This uses new capture analyysis to capture s={}", s);
1112
};
1213
}

src/test/ui/closures/2229_closure_analysis/feature-gate-capture_disjoint_fields.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
error[E0658]: attributes on expressions are experimental
22
--> $DIR/feature-gate-capture_disjoint_fields.rs:8:13
33
|
4-
LL | let c = #[rustc_capture_analysis] || {
4+
LL | let c = #[rustc_capture_analysis]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,20 @@
11
For closure=DefId(0:4 ~ feature_gate_capture_disjoint_fields[317d]::main::{closure#0}): Using new-style capture analysis
2+
For closure=DefId(0:4 ~ feature_gate_capture_disjoint_fields[317d]::main::{closure#0}): capture information: {
3+
Place {
4+
base_ty: std::string::String,
5+
base: Upvar(
6+
UpvarId(HirId { owner: DefId(0:3 ~ feature_gate_capture_disjoint_fields[317d]::main), local_id: 1 };`s`;DefId(0:4 ~ feature_gate_capture_disjoint_fields[317d]::main::{closure#0})),
7+
),
8+
projections: [],
9+
}: CaptureInfo {
10+
expr_id: Some(
11+
HirId {
12+
owner: DefId(0:3 ~ feature_gate_capture_disjoint_fields[317d]::main),
13+
local_id: 52,
14+
},
15+
),
16+
capture_kind: ByRef(
17+
UpvarBorrow(ImmBorrow, '_#50r),
18+
),
19+
},
20+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// FIXME(arora-aman) add run-pass once 2229 is implemented
2+
3+
#![feature(capture_disjoint_fields)]
4+
//~^ warning the feature `capture_disjoint_fields` is incomplete
5+
#![feature(rustc_attrs)]
6+
7+
struct Filter {
8+
div: i32,
9+
}
10+
impl Filter {
11+
fn allowed(&self, x: i32) -> bool {
12+
x % self.div == 1
13+
}
14+
}
15+
16+
struct Data {
17+
filter: Filter,
18+
list: Vec<i32>,
19+
}
20+
impl Data {
21+
fn update(&mut self) {
22+
// The closure passed to filter only captures self.filter,
23+
// therefore mutating self.list is allowed.
24+
self.list.retain(
25+
//~^ cannot borrow `self.list` as mutable because it is also borrowed as immutable
26+
#[rustc_capture_analysis]
27+
|v| self.filter.allowed(*v),
28+
);
29+
}
30+
}
31+
32+
fn main() {
33+
let mut d = Data { filter: Filter { div: 3 }, list: Vec::new() };
34+
35+
for i in 1..10 {
36+
d.list.push(i);
37+
}
38+
39+
d.update();
40+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/filter-on-struct-member.rs:1: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+
error[E0502]: cannot borrow `self.list` as mutable because it is also borrowed as immutable
11+
--> $DIR/filter-on-struct-member.rs:22:9
12+
|
13+
LL | self.list.retain(
14+
| ^ ------ immutable borrow later used by call
15+
| _________|
16+
| |
17+
LL | |
18+
LL | | #[rustc_capture_analysis]
19+
LL | | |v| self.filter.allowed(*v),
20+
| | --- ---- first borrow occurs due to use of `self` in closure
21+
| | |
22+
| | immutable borrow occurs here
23+
LL | | );
24+
| |_________^ mutable borrow occurs here
25+
26+
error: aborting due to previous error; 1 warning emitted
27+
28+
For more information about this error, try `rustc --explain E0502`.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
For closure=DefId(0:12 ~ filter_on_struct_member[317d]::{impl#1}::update::{closure#0}): Using new-style capture analysis
2+
For closure=DefId(0:12 ~ filter_on_struct_member[317d]::{impl#1}::update::{closure#0}): capture information: {
3+
Place {
4+
base_ty: &mut Data,
5+
base: Upvar(
6+
UpvarId(HirId { owner: DefId(0:11 ~ filter_on_struct_member[317d]::{impl#1}::update), local_id: 1 };`self`;DefId(0:12 ~ filter_on_struct_member[317d]::{impl#1}::update::{closure#0})),
7+
),
8+
projections: [
9+
Projection {
10+
ty: Data,
11+
kind: Deref,
12+
},
13+
Projection {
14+
ty: Filter,
15+
kind: Field(
16+
0,
17+
0,
18+
),
19+
},
20+
],
21+
}: CaptureInfo {
22+
expr_id: Some(
23+
HirId {
24+
owner: DefId(0:11 ~ filter_on_struct_member[317d]::{impl#1}::update),
25+
local_id: 13,
26+
},
27+
),
28+
capture_kind: ByRef(
29+
UpvarBorrow(ImmBorrow, '_#7r),
30+
),
31+
},
32+
}

0 commit comments

Comments
 (0)