Add initial set of testcases for RFC 2229
Co-authored-by: Dhruv Jauhar <dhruvjhr@gmail.com>
This commit is contained in:
parent
88310cc0eb
commit
58e8f8fd2c
34 changed files with 914 additions and 2 deletions
|
@ -169,6 +169,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
)
|
||||
.consume_body(body);
|
||||
|
||||
log_capture_analysis!(
|
||||
self,
|
||||
closure_def_id,
|
||||
"capture information: {:#?}",
|
||||
delegate.capture_information
|
||||
);
|
||||
|
||||
if let Some(closure_substs) = infer_kind {
|
||||
// Unify the (as yet unbound) type variable in the closure
|
||||
// substs with the kind we inferred.
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// Ensure that capture analysis results in arrays being completely captured.
|
||||
fn main() {
|
||||
let mut m = [1, 2, 3, 4, 5];
|
||||
|
||||
let mut c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
m[0] += 10;
|
||||
m[1] += 40;
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/arrays-completely-captured.rs:9:17
|
||||
|
|
||||
LL | let mut c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/arrays-completely-captured.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,20 @@
|
|||
For closure=DefId(0:4 ~ arrays_completely_captured[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:4 ~ arrays_completely_captured[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: [i32; 5],
|
||||
base: Upvar(
|
||||
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})),
|
||||
),
|
||||
projections: [],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:3 ~ arrays_completely_captured[317d]::main),
|
||||
local_id: 12,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(MutBorrow, '_#6r),
|
||||
),
|
||||
},
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// FIXME(arora-aman) add run-pass once 2229 is implemented
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut p = Point { x: 10, y: 10 };
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
println!("{}", p.x);
|
||||
};
|
||||
|
||||
// `c` should only capture `p.x`, therefore mutating `p.y` is allowed.
|
||||
let py = &mut p.y;
|
||||
|
||||
c();
|
||||
*py = 20;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/capture-disjoint-field-struct.rs:15:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/capture-disjoint-field-struct.rs:3:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,28 @@
|
|||
For closure=DefId(0:7 ~ capture_disjoint_field_struct[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:7 ~ capture_disjoint_field_struct[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: Point,
|
||||
base: Upvar(
|
||||
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})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: i32,
|
||||
kind: Field(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:6 ~ capture_disjoint_field_struct[317d]::main),
|
||||
local_id: 31,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#35r),
|
||||
),
|
||||
},
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// FIXME(arora-aman) add run-pass once 2229 is implemented
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn main() {
|
||||
let mut t = (10, 10);
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
println!("{}", t.0);
|
||||
};
|
||||
|
||||
// `c` only captures t.0, therefore mutating t.1 is allowed.
|
||||
let t1 = &mut t.1;
|
||||
|
||||
c();
|
||||
*t1 = 20;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/capture-disjoint-field-tuple.rs:8:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/capture-disjoint-field-tuple.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,28 @@
|
|||
For closure=DefId(0:4 ~ capture_disjoint_field_tuple[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:4 ~ capture_disjoint_field_tuple[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: (i32, i32),
|
||||
base: Upvar(
|
||||
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})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: i32,
|
||||
kind: Field(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:3 ~ capture_disjoint_field_tuple[317d]::main),
|
||||
local_id: 28,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#35r),
|
||||
),
|
||||
},
|
||||
}
|
|
@ -5,8 +5,9 @@
|
|||
fn main() {
|
||||
let s = format!("s");
|
||||
|
||||
let c = #[rustc_capture_analysis] || {
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
println!("This uses new capture analyysis to capture s={}", s);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/feature-gate-capture_disjoint_fields.rs:8:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis] || {
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
|
|
|
@ -1 +1,20 @@
|
|||
For closure=DefId(0:4 ~ feature_gate_capture_disjoint_fields[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:4 ~ feature_gate_capture_disjoint_fields[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: std::string::String,
|
||||
base: Upvar(
|
||||
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})),
|
||||
),
|
||||
projections: [],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:3 ~ feature_gate_capture_disjoint_fields[317d]::main),
|
||||
local_id: 52,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#50r),
|
||||
),
|
||||
},
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// FIXME(arora-aman) add run-pass once 2229 is implemented
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ warning the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Filter {
|
||||
div: i32,
|
||||
}
|
||||
impl Filter {
|
||||
fn allowed(&self, x: i32) -> bool {
|
||||
x % self.div == 1
|
||||
}
|
||||
}
|
||||
|
||||
struct Data {
|
||||
filter: Filter,
|
||||
list: Vec<i32>,
|
||||
}
|
||||
impl Data {
|
||||
fn update(&mut self) {
|
||||
// The closure passed to filter only captures self.filter,
|
||||
// therefore mutating self.list is allowed.
|
||||
self.list.retain(
|
||||
//~^ cannot borrow `self.list` as mutable because it is also borrowed as immutable
|
||||
#[rustc_capture_analysis]
|
||||
|v| self.filter.allowed(*v),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut d = Data { filter: Filter { div: 3 }, list: Vec::new() };
|
||||
|
||||
for i in 1..10 {
|
||||
d.list.push(i);
|
||||
}
|
||||
|
||||
d.update();
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/filter-on-struct-member.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error[E0502]: cannot borrow `self.list` as mutable because it is also borrowed as immutable
|
||||
--> $DIR/filter-on-struct-member.rs:22:9
|
||||
|
|
||||
LL | self.list.retain(
|
||||
| ^ ------ immutable borrow later used by call
|
||||
| _________|
|
||||
| |
|
||||
LL | |
|
||||
LL | | #[rustc_capture_analysis]
|
||||
LL | | |v| self.filter.allowed(*v),
|
||||
| | --- ---- first borrow occurs due to use of `self` in closure
|
||||
| | |
|
||||
| | immutable borrow occurs here
|
||||
LL | | );
|
||||
| |_________^ mutable borrow occurs here
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0502`.
|
|
@ -0,0 +1,32 @@
|
|||
For closure=DefId(0:12 ~ filter_on_struct_member[317d]::{impl#1}::update::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:12 ~ filter_on_struct_member[317d]::{impl#1}::update::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: &mut Data,
|
||||
base: Upvar(
|
||||
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})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: Data,
|
||||
kind: Deref,
|
||||
},
|
||||
Projection {
|
||||
ty: Filter,
|
||||
kind: Field(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:11 ~ filter_on_struct_member[317d]::{impl#1}::update),
|
||||
local_id: 13,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#7r),
|
||||
),
|
||||
},
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ warning the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(unused)]
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
struct Wrapper {
|
||||
p: Point,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut w = Wrapper { p: Point { x: 10, y: 10 } };
|
||||
|
||||
// Only paths that appears within the closure that directly start off
|
||||
// a variable defined outside the closure are captured.
|
||||
//
|
||||
// Therefore `w.p` is captured
|
||||
// Note that `wp.x` doesn't start off a variable defined outside the closure.
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
let wp = &w.p;
|
||||
println!("{}", wp.x);
|
||||
};
|
||||
|
||||
// Since `c` captures `w.p` by an ImmBorrow, `w.p.y` can't be mutated.
|
||||
let py = &mut w.p.y;
|
||||
c();
|
||||
|
||||
*py = 20
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/multilevel-path-1.rs:22:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/multilevel-path-1.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,28 @@
|
|||
For closure=DefId(0:9 ~ multilevel_path_1[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:9 ~ multilevel_path_1[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: Wrapper,
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:8 ~ multilevel_path_1[317d]::main), local_id: 1 };`w`;DefId(0:9 ~ multilevel_path_1[317d]::main::{closure#0})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: Point,
|
||||
kind: Field(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:8 ~ multilevel_path_1[317d]::main),
|
||||
local_id: 20,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#37r),
|
||||
),
|
||||
},
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// FIXME(arora-aman) add run-pass once 2229 is implemented
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ warning the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(unused)]
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
struct Wrapper {
|
||||
p: Point,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut w = Wrapper { p: Point { x: 10, y: 10 } };
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
println!("{}", w.p.x);
|
||||
};
|
||||
|
||||
// `c` only captures `w.p.x`, therefore it's safe to mutate `w.p.y`.
|
||||
let py = &mut w.p.y;
|
||||
c();
|
||||
|
||||
*py = 20
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/multilevel-path-2.rs:19:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/multilevel-path-2.rs:3:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,35 @@
|
|||
For closure=DefId(0:9 ~ multilevel_path_2[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:9 ~ multilevel_path_2[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: Wrapper,
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:8 ~ multilevel_path_2[317d]::main), local_id: 1 };`w`;DefId(0:9 ~ multilevel_path_2[317d]::main::{closure#0})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: Point,
|
||||
kind: Field(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
},
|
||||
Projection {
|
||||
ty: i32,
|
||||
kind: Field(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:8 ~ multilevel_path_2[317d]::main),
|
||||
local_id: 35,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#35r),
|
||||
),
|
||||
},
|
||||
}
|
40
src/test/ui/closures/2229_closure_analysis/nested-closure.rs
Normal file
40
src/test/ui/closures/2229_closure_analysis/nested-closure.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
// FIXME(arora-aman) add run-pass once 2229 is implemented
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ warning the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
// This testcase ensures that nested closures are handles properly
|
||||
// - The nested closure is analyzed first.
|
||||
// - The capture kind of the nested closure is accounted for by the enclosing closure
|
||||
// - Any captured path by the nested closure that starts off a local variable in the enclosing
|
||||
// closure is not listed as a capture of the enclosing closure.
|
||||
|
||||
fn main() {
|
||||
let mut p = Point { x: 5, y: 20 };
|
||||
|
||||
let mut c1 = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
println!("{}", p.x);
|
||||
let incr = 10;
|
||||
let mut c2 = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| p.y += incr;
|
||||
c2();
|
||||
println!("{}", p.y);
|
||||
};
|
||||
|
||||
c1();
|
||||
|
||||
let px = &p.x;
|
||||
|
||||
println!("{}", px);
|
||||
|
||||
c1();
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/nested-closure.rs:19:18
|
||||
|
|
||||
LL | let mut c1 = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/nested-closure.rs:24:22
|
||||
|
|
||||
LL | let mut c2 = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/nested-closure.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,98 @@
|
|||
For closure=DefId(0:8 ~ nested_closure[317d]::main::{closure#0}::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:8 ~ nested_closure[317d]::main::{closure#0}::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: Point,
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:6 ~ nested_closure[317d]::main), local_id: 1 };`p`;DefId(0:8 ~ nested_closure[317d]::main::{closure#0}::{closure#0})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: i32,
|
||||
kind: Field(
|
||||
1,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:6 ~ nested_closure[317d]::main),
|
||||
local_id: 70,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(MutBorrow, '_#109r),
|
||||
),
|
||||
},
|
||||
Place {
|
||||
base_ty: i32,
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:6 ~ nested_closure[317d]::main), local_id: 5 };`incr`;DefId(0:8 ~ nested_closure[317d]::main::{closure#0}::{closure#0})),
|
||||
),
|
||||
projections: [],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:6 ~ nested_closure[317d]::main),
|
||||
local_id: 72,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#110r),
|
||||
),
|
||||
},
|
||||
}
|
||||
For closure=DefId(0:7 ~ nested_closure[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:7 ~ nested_closure[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: Point,
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:6 ~ nested_closure[317d]::main), local_id: 1 };`p`;DefId(0:7 ~ nested_closure[317d]::main::{closure#0})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: i32,
|
||||
kind: Field(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:6 ~ nested_closure[317d]::main),
|
||||
local_id: 37,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#114r),
|
||||
),
|
||||
},
|
||||
Place {
|
||||
base_ty: Point,
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:6 ~ nested_closure[317d]::main), local_id: 1 };`p`;DefId(0:7 ~ nested_closure[317d]::main::{closure#0})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: i32,
|
||||
kind: Field(
|
||||
1,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:6 ~ nested_closure[317d]::main),
|
||||
local_id: 70,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(MutBorrow, '_#115r),
|
||||
),
|
||||
},
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Point {
|
||||
x: f32,
|
||||
y: f32,
|
||||
}
|
||||
|
||||
struct Pentagon {
|
||||
points: [Point; 5],
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let p1 = Point { x: 10.0, y: 10.0 };
|
||||
let p2 = Point { x: 7.5, y: 12.5 };
|
||||
let p3 = Point { x: 15.0, y: 15.0 };
|
||||
let p4 = Point { x: 12.5, y: 12.5 };
|
||||
let p5 = Point { x: 20.0, y: 10.0 };
|
||||
|
||||
let pent = Pentagon { points: [p1, p2, p3, p4, p5] };
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
println!("{}", pent.points[5].x);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/path-with-array-access.rs:23:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/path-with-array-access.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,28 @@
|
|||
For closure=DefId(0:10 ~ path_with_array_access[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:10 ~ path_with_array_access[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: Pentagon,
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:9 ~ path_with_array_access[317d]::main), local_id: 6 };`pent`;DefId(0:10 ~ path_with_array_access[317d]::main::{closure#0})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: [Point; 5],
|
||||
kind: Field(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:9 ~ path_with_array_access[317d]::main),
|
||||
local_id: 83,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#34r),
|
||||
),
|
||||
},
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// FIXME(arora-aman) add run-pass once 2229 is implemented
|
||||
|
||||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// Test to ensure that min analysis meets capture kind for all paths captured.
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut p = Point { x: 10, y: 20 };
|
||||
|
||||
//
|
||||
// Requirements:
|
||||
// p.x -> MutBoorrow
|
||||
// p -> ImmBorrow
|
||||
//
|
||||
// Requirements met when p is captured via MutBorrow
|
||||
//
|
||||
let mut c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
p.x += 10;
|
||||
println!("{:?}", p);
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/simple-struct-min-capture.rs:25:17
|
||||
|
|
||||
LL | let mut c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/simple-struct-min-capture.rs:3:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,45 @@
|
|||
For closure=DefId(0:4 ~ simple_struct_min_capture[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:4 ~ simple_struct_min_capture[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: Point,
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:3 ~ simple_struct_min_capture[317d]::main), local_id: 1 };`p`;DefId(0:4 ~ simple_struct_min_capture[317d]::main::{closure#0})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: i32,
|
||||
kind: Field(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:3 ~ simple_struct_min_capture[317d]::main),
|
||||
local_id: 15,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(MutBorrow, '_#34r),
|
||||
),
|
||||
},
|
||||
Place {
|
||||
base_ty: Point,
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:3 ~ simple_struct_min_capture[317d]::main), local_id: 1 };`p`;DefId(0:4 ~ simple_struct_min_capture[317d]::main::{closure#0})),
|
||||
),
|
||||
projections: [],
|
||||
}: CaptureInfo {
|
||||
expr_id: Some(
|
||||
HirId {
|
||||
owner: DefId(0:3 ~ simple_struct_min_capture[317d]::main),
|
||||
local_id: 35,
|
||||
},
|
||||
),
|
||||
capture_kind: ByRef(
|
||||
UpvarBorrow(ImmBorrow, '_#35r),
|
||||
),
|
||||
},
|
||||
}
|
28
src/test/ui/closures/2229_closure_analysis/slice-pat.rs
Normal file
28
src/test/ui/closures/2229_closure_analysis/slice-pat.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
#![feature(capture_disjoint_fields)]
|
||||
//~^ WARNING the feature `capture_disjoint_fields` is incomplete
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// Test to ensure Index projections are handled properly during capture analysis
|
||||
//
|
||||
// The array should be moved in entirety, even though only some elements are used.
|
||||
|
||||
fn main() {
|
||||
let arr : [String; 5] = [
|
||||
format!("A"),
|
||||
format!("B"),
|
||||
format!("C"),
|
||||
format!("D"),
|
||||
format!("E")
|
||||
];
|
||||
|
||||
let c = #[rustc_capture_analysis]
|
||||
//~^ ERROR: attributes on expressions are experimental
|
||||
|| {
|
||||
let [a, b, .., e] = arr;
|
||||
assert_eq!(a, "A");
|
||||
assert_eq!(b, "B");
|
||||
assert_eq!(e, "E");
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
21
src/test/ui/closures/2229_closure_analysis/slice-pat.stderr
Normal file
21
src/test/ui/closures/2229_closure_analysis/slice-pat.stderr
Normal file
|
@ -0,0 +1,21 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/slice-pat.rs:18:13
|
||||
|
|
||||
LL | let c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/slice-pat.rs:1:12
|
||||
|
|
||||
LL | #![feature(capture_disjoint_fields)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
20
src/test/ui/closures/2229_closure_analysis/slice-pat.stdout
Normal file
20
src/test/ui/closures/2229_closure_analysis/slice-pat.stdout
Normal file
|
@ -0,0 +1,20 @@
|
|||
For closure=DefId(0:5 ~ slice_pat[317d]::main::{closure#0}): Using new-style capture analysis
|
||||
For closure=DefId(0:5 ~ slice_pat[317d]::main::{closure#0}): capture information: {
|
||||
Place {
|
||||
base_ty: [std::string::String; 5],
|
||||
base: Upvar(
|
||||
UpvarId(HirId { owner: DefId(0:3 ~ slice_pat[317d]::main), local_id: 1 };`arr`;DefId(0:5 ~ slice_pat[317d]::main::{closure#0})),
|
||||
),
|
||||
projections: [
|
||||
Projection {
|
||||
ty: std::string::String,
|
||||
kind: Index,
|
||||
},
|
||||
],
|
||||
}: CaptureInfo {
|
||||
expr_id: None,
|
||||
capture_kind: ByValue(
|
||||
None,
|
||||
),
|
||||
},
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue