mirror of https://github.com/rust-lang/rust
234 lines
8.0 KiB
Rust
234 lines
8.0 KiB
Rust
//@ edition:2021
|
|
|
|
// Test that move closures drop derefs with `capture_disjoint_fields` enabled.
|
|
|
|
#![feature(rustc_attrs)]
|
|
|
|
fn simple_move_closure() {
|
|
struct S(String);
|
|
struct T(S);
|
|
|
|
let t = T(S("s".into()));
|
|
let mut c = #[rustc_capture_analysis]
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
move || {
|
|
//~^ ERROR: First Pass analysis includes:
|
|
//~| ERROR: Min Capture analysis includes:
|
|
t.0.0 = "new S".into();
|
|
//~^ NOTE: Capturing t[(0, 0),(0, 0)] -> MutBorrow
|
|
//~| NOTE: Min Capture t[(0, 0),(0, 0)] -> ByValue
|
|
};
|
|
c();
|
|
}
|
|
|
|
// Test move closure use reborrows when using references
|
|
fn simple_ref() {
|
|
let mut s = 10;
|
|
let ref_s = &mut s;
|
|
|
|
let mut c = #[rustc_capture_analysis]
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
move || {
|
|
//~^ ERROR: First Pass analysis includes:
|
|
//~| ERROR: Min Capture analysis includes:
|
|
*ref_s += 10;
|
|
//~^ NOTE: Capturing ref_s[Deref] -> MutBorrow
|
|
//~| NOTE: Min Capture ref_s[] -> ByValue
|
|
};
|
|
c();
|
|
}
|
|
|
|
// Test move closure use reborrows when using references
|
|
fn struct_contains_ref_to_another_struct_1() {
|
|
struct S(String);
|
|
struct T<'a>(&'a mut S);
|
|
|
|
let mut s = S("s".into());
|
|
let t = T(&mut s);
|
|
|
|
let mut c = #[rustc_capture_analysis]
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
move || {
|
|
//~^ ERROR: First Pass analysis includes:
|
|
//~| ERROR: Min Capture analysis includes:
|
|
t.0.0 = "new s".into();
|
|
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> MutBorrow
|
|
//~| NOTE: Min Capture t[(0, 0)] -> ByValue
|
|
};
|
|
|
|
c();
|
|
}
|
|
|
|
// Test that we can use reborrows to read data of Copy types
|
|
// i.e. without truncating derefs
|
|
fn struct_contains_ref_to_another_struct_2() {
|
|
struct S(i32);
|
|
struct T<'a>(&'a S);
|
|
|
|
let s = S(0);
|
|
let t = T(&s);
|
|
|
|
let mut c = #[rustc_capture_analysis]
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
move || {
|
|
//~^ ERROR: First Pass analysis includes:
|
|
//~| ERROR: Min Capture analysis includes:
|
|
let _t = t.0.0;
|
|
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
|
|
//~| NOTE: Min Capture t[(0, 0)] -> ByValue
|
|
};
|
|
|
|
c();
|
|
}
|
|
|
|
// Test that we can use truncate to move out of !Copy types
|
|
fn struct_contains_ref_to_another_struct_3() {
|
|
struct S(String);
|
|
struct T<'a>(&'a S);
|
|
|
|
let s = S("s".into());
|
|
let t = T(&s);
|
|
|
|
let mut c = #[rustc_capture_analysis]
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
move || {
|
|
//~^ ERROR: First Pass analysis includes:
|
|
//~| ERROR: Min Capture analysis includes:
|
|
let _t = t.0.0;
|
|
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ByValue
|
|
//~| NOTE: Min Capture t[(0, 0)] -> ByValue
|
|
};
|
|
|
|
c();
|
|
}
|
|
|
|
// Test that derefs of box are truncated in move closures
|
|
fn truncate_box_derefs() {
|
|
struct S(i32);
|
|
|
|
|
|
// Content within the box is moved within the closure
|
|
let b = Box::new(S(10));
|
|
let c = #[rustc_capture_analysis]
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
move || {
|
|
//~^ ERROR: First Pass analysis includes:
|
|
//~| ERROR: Min Capture analysis includes:
|
|
let _t = b.0;
|
|
//~^ NOTE: Capturing b[Deref,(0, 0)] -> ImmBorrow
|
|
//~| NOTE: Min Capture b[] -> ByValue
|
|
};
|
|
|
|
c();
|
|
|
|
// Content within the box is used by a shared ref and the box is the root variable
|
|
let b = Box::new(S(10));
|
|
|
|
let c = #[rustc_capture_analysis]
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
move || {
|
|
//~^ ERROR: First Pass analysis includes:
|
|
//~| ERROR: Min Capture analysis includes:
|
|
println!("{}", b.0);
|
|
//~^ NOTE: Capturing b[Deref,(0, 0)] -> ImmBorrow
|
|
//~| NOTE: Min Capture b[] -> ByValue
|
|
};
|
|
|
|
c();
|
|
|
|
// Content within the box is used by a shared ref and the box is not the root variable
|
|
let b = Box::new(S(10));
|
|
let t = (0, b);
|
|
|
|
let c = #[rustc_capture_analysis]
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
move || {
|
|
//~^ ERROR: First Pass analysis includes:
|
|
//~| ERROR: Min Capture analysis includes:
|
|
println!("{}", t.1.0);
|
|
//~^ NOTE: Capturing t[(1, 0),Deref,(0, 0)] -> ImmBorrow
|
|
//~| NOTE: Min Capture t[(1, 0)] -> ByValue
|
|
};
|
|
}
|
|
|
|
struct Foo { x: i32 }
|
|
|
|
// Ensure that even in move closures, if the data is not owned by the root variable
|
|
// then we don't truncate the derefs or a ByValue capture, rather do a reborrow
|
|
fn box_mut_1() {
|
|
let mut foo = Foo { x: 0 } ;
|
|
|
|
let p_foo = &mut foo;
|
|
let box_p_foo = Box::new(p_foo);
|
|
|
|
let c = #[rustc_capture_analysis] move || box_p_foo.x += 10;
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
//~| First Pass analysis includes:
|
|
//~| NOTE: Capturing box_p_foo[Deref,Deref,(0, 0)] -> MutBorrow
|
|
//~| Min Capture analysis includes:
|
|
//~| NOTE: Min Capture box_p_foo[] -> ByValue
|
|
}
|
|
|
|
// Ensure that even in move closures, if the data is not owned by the root variable
|
|
// then we don't truncate the derefs or a ByValue capture, rather do a reborrow
|
|
fn box_mut_2() {
|
|
let foo = Foo { x: 0 } ;
|
|
|
|
let mut box_foo = Box::new(foo);
|
|
let p_foo = &mut box_foo;
|
|
|
|
let c = #[rustc_capture_analysis] move || p_foo.x += 10;
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
//~| First Pass analysis includes:
|
|
//~| NOTE: Capturing p_foo[Deref,Deref,(0, 0)] -> MutBorrow
|
|
//~| Min Capture analysis includes:
|
|
//~| NOTE: Min Capture p_foo[] -> ByValue
|
|
}
|
|
|
|
// Test that move closures can take ownership of Copy type
|
|
fn returned_closure_owns_copy_type_data() -> impl Fn() -> i32 {
|
|
let x = 10;
|
|
|
|
let c = #[rustc_capture_analysis] move || x;
|
|
//~^ ERROR: attributes on expressions are experimental
|
|
//~| NOTE: see issue #15701 <https://github.com/rust-lang/rust/issues/15701>
|
|
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
//~| First Pass analysis includes:
|
|
//~| NOTE: Capturing x[] -> ImmBorrow
|
|
//~| Min Capture analysis includes:
|
|
//~| NOTE: Min Capture x[] -> ByValue
|
|
|
|
c
|
|
}
|
|
|
|
fn main() {
|
|
simple_move_closure();
|
|
simple_ref();
|
|
struct_contains_ref_to_another_struct_1();
|
|
struct_contains_ref_to_another_struct_2();
|
|
struct_contains_ref_to_another_struct_3();
|
|
truncate_box_derefs();
|
|
box_mut_2();
|
|
box_mut_1();
|
|
}
|