Treat read of COpy types via refs as not move in move-closure
This commit is contained in:
parent
e39c3c05a4
commit
1b86ad8485
|
@ -1116,14 +1116,21 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||
place_with_id, diag_expr_id, mode
|
||||
);
|
||||
|
||||
let place = truncate_capture_for_move(place_with_id.place.clone());
|
||||
match (self.capture_clause, mode) {
|
||||
// In non-move closures, we only care about moves
|
||||
(hir::CaptureBy::Ref, euv::Copy) => return,
|
||||
|
||||
// We want to capture Copy types that read through a ref via a reborrow
|
||||
(hir::CaptureBy::Value, euv::Copy)
|
||||
if place_with_id.place.deref_tys().any(ty::TyS::is_ref) =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
(hir::CaptureBy::Ref, euv::Move) | (hir::CaptureBy::Value, euv::Move | euv::Copy) => {}
|
||||
};
|
||||
|
||||
let place = truncate_capture_for_move(place_with_id.place.clone());
|
||||
let place_with_id = PlaceWithHirId { place: place.clone(), hir_id: place_with_id.hir_id };
|
||||
|
||||
if !self.capture_information.contains_key(&place) {
|
||||
|
|
|
@ -6,7 +6,25 @@
|
|||
//~| NOTE: see issue #53488 <https://github.com/rust-lang/rust/issues/53488>
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
// Test we truncate derefs properly
|
||||
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>
|
||||
move || {
|
||||
//~^ ERROR: First Pass analysis includes:
|
||||
//~| ERROR: Min Capture analysis includes:
|
||||
t.0.0 = "new S".into();
|
||||
//~^ NOTE: Capturing t[(0, 0),(0, 0)] -> ByValue
|
||||
//~| 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;
|
||||
|
@ -24,8 +42,8 @@ fn simple_ref() {
|
|||
c();
|
||||
}
|
||||
|
||||
// Test we truncate derefs properly
|
||||
fn struct_contains_ref_to_another_struct() {
|
||||
// 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);
|
||||
|
||||
|
@ -46,27 +64,78 @@ fn struct_contains_ref_to_another_struct() {
|
|||
c();
|
||||
}
|
||||
|
||||
// Test that we don't reduce precision when there is nothing deref.
|
||||
fn no_ref() {
|
||||
struct S(String);
|
||||
struct T(S);
|
||||
// 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 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>
|
||||
move || {
|
||||
//~^ ERROR: First Pass analysis includes:
|
||||
//~| ERROR: Min Capture analysis includes:
|
||||
t.0.0 = "new S".into();
|
||||
//~^ NOTE: Capturing t[(0, 0),(0, 0)] -> ByValue
|
||||
//~| NOTE: Min Capture t[(0, 0),(0, 0)] -> ByValue
|
||||
let _t = t.0.0;
|
||||
//~^ NOTE: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
|
||||
//~| NOTE: Min Capture t[(0, 0),Deref,(0, 0)] -> ImmBorrow
|
||||
};
|
||||
|
||||
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>
|
||||
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: Capturing t[(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);
|
||||
|
||||
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>
|
||||
move || {
|
||||
//~^ ERROR: First Pass analysis includes:
|
||||
//~| ERROR: Min Capture analysis includes:
|
||||
let _t = b.0;
|
||||
//~^ NOTE: Capturing b[Deref,(0, 0)] -> ByValue
|
||||
//~| NOTE: Capturing b[] -> ByValue
|
||||
//~| NOTE: Min Capture b[] -> ByValue
|
||||
};
|
||||
|
||||
c();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
simple_move_closure();
|
||||
simple_ref();
|
||||
struct_contains_ref_to_another_struct();
|
||||
no_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();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | let mut c = #[rustc_capture_analysis]
|
|||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/move_closure.rs:35:17
|
||||
--> $DIR/move_closure.rs:32:17
|
||||
|
|
||||
LL | let mut c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -17,7 +17,7 @@ LL | let mut c = #[rustc_capture_analysis]
|
|||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/move_closure.rs:55:17
|
||||
--> $DIR/move_closure.rs:53:17
|
||||
|
|
||||
LL | let mut c = #[rustc_capture_analysis]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -25,6 +25,33 @@ 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
|
||||
|
||||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/move_closure.rs:76: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
|
||||
|
||||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/move_closure.rs:98: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
|
||||
|
||||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/move_closure.rs:119: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/move_closure.rs:3:12
|
||||
|
|
||||
|
@ -40,78 +67,6 @@ error: First Pass analysis includes:
|
|||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | *ref_s += 10;
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing ref_s[Deref] -> UniqueImmBorrow
|
||||
--> $DIR/move_closure.rs:20:9
|
||||
|
|
||||
LL | *ref_s += 10;
|
||||
| ^^^^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/move_closure.rs:17:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | *ref_s += 10;
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture ref_s[Deref] -> UniqueImmBorrow
|
||||
--> $DIR/move_closure.rs:20:9
|
||||
|
|
||||
LL | *ref_s += 10;
|
||||
| ^^^^^^
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/move_closure.rs:38:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | t.0.0 = "new s".into();
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow
|
||||
--> $DIR/move_closure.rs:41:9
|
||||
|
|
||||
LL | t.0.0 = "new s".into();
|
||||
| ^^^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/move_closure.rs:38:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | t.0.0 = "new s".into();
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow
|
||||
--> $DIR/move_closure.rs:41:9
|
||||
|
|
||||
LL | t.0.0 = "new s".into();
|
||||
| ^^^^^
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/move_closure.rs:58:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | t.0.0 = "new S".into();
|
||||
LL | |
|
||||
LL | |
|
||||
|
@ -119,13 +74,13 @@ LL | | };
|
|||
| |_____^
|
||||
|
|
||||
note: Capturing t[(0, 0),(0, 0)] -> ByValue
|
||||
--> $DIR/move_closure.rs:61:9
|
||||
--> $DIR/move_closure.rs:20:9
|
||||
|
|
||||
LL | t.0.0 = "new S".into();
|
||||
| ^^^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/move_closure.rs:58:5
|
||||
--> $DIR/move_closure.rs:17:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
|
@ -137,11 +92,201 @@ LL | | };
|
|||
| |_____^
|
||||
|
|
||||
note: Min Capture t[(0, 0),(0, 0)] -> ByValue
|
||||
--> $DIR/move_closure.rs:61:9
|
||||
--> $DIR/move_closure.rs:20:9
|
||||
|
|
||||
LL | t.0.0 = "new S".into();
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 9 previous errors; 1 warning emitted
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/move_closure.rs:35:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | *ref_s += 10;
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing ref_s[Deref] -> UniqueImmBorrow
|
||||
--> $DIR/move_closure.rs:38:9
|
||||
|
|
||||
LL | *ref_s += 10;
|
||||
| ^^^^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/move_closure.rs:35:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | *ref_s += 10;
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture ref_s[Deref] -> UniqueImmBorrow
|
||||
--> $DIR/move_closure.rs:38:9
|
||||
|
|
||||
LL | *ref_s += 10;
|
||||
| ^^^^^^
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/move_closure.rs:56:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | t.0.0 = "new s".into();
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow
|
||||
--> $DIR/move_closure.rs:59:9
|
||||
|
|
||||
LL | t.0.0 = "new s".into();
|
||||
| ^^^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/move_closure.rs:56:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | t.0.0 = "new s".into();
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture t[(0, 0),Deref,(0, 0)] -> UniqueImmBorrow
|
||||
--> $DIR/move_closure.rs:59:9
|
||||
|
|
||||
LL | t.0.0 = "new s".into();
|
||||
| ^^^^^
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/move_closure.rs:79:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _t = t.0.0;
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
|
||||
--> $DIR/move_closure.rs:82:18
|
||||
|
|
||||
LL | let _t = t.0.0;
|
||||
| ^^^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/move_closure.rs:79:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _t = t.0.0;
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture t[(0, 0),Deref,(0, 0)] -> ImmBorrow
|
||||
--> $DIR/move_closure.rs:82:18
|
||||
|
|
||||
LL | let _t = t.0.0;
|
||||
| ^^^^^
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/move_closure.rs:101:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _t = t.0.0;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing t[(0, 0),Deref,(0, 0)] -> ImmBorrow
|
||||
--> $DIR/move_closure.rs:104:18
|
||||
|
|
||||
LL | let _t = t.0.0;
|
||||
| ^^^^^
|
||||
note: Capturing t[(0, 0)] -> ByValue
|
||||
--> $DIR/move_closure.rs:104:18
|
||||
|
|
||||
LL | let _t = t.0.0;
|
||||
| ^^^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/move_closure.rs:101:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _t = t.0.0;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture t[(0, 0)] -> ByValue
|
||||
--> $DIR/move_closure.rs:104:18
|
||||
|
|
||||
LL | let _t = t.0.0;
|
||||
| ^^^^^
|
||||
|
||||
error: First Pass analysis includes:
|
||||
--> $DIR/move_closure.rs:122:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _t = b.0;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Capturing b[Deref,(0, 0)] -> ByValue
|
||||
--> $DIR/move_closure.rs:125:18
|
||||
|
|
||||
LL | let _t = b.0;
|
||||
| ^^^
|
||||
note: Capturing b[] -> ByValue
|
||||
--> $DIR/move_closure.rs:125:18
|
||||
|
|
||||
LL | let _t = b.0;
|
||||
| ^^^
|
||||
|
||||
error: Min Capture analysis includes:
|
||||
--> $DIR/move_closure.rs:122:5
|
||||
|
|
||||
LL | / move || {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | let _t = b.0;
|
||||
... |
|
||||
LL | |
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
note: Min Capture b[] -> ByValue
|
||||
--> $DIR/move_closure.rs:125:18
|
||||
|
|
||||
LL | let _t = b.0;
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 18 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
Loading…
Reference in New Issue