Skip to content

Commit 015c6a2

Browse files
committed
don't capture derefs in case of by value capture
1 parent 20692cb commit 015c6a2

File tree

2 files changed

+16
-14
lines changed

2 files changed

+16
-14
lines changed

compiler/rustc_typeck/src/check/upvar.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
385385
base => bug!("Expected upvar, found={:?}", base),
386386
};
387387

388-
let place = truncate_projections_for_capture(place, inferred_info.capture_clause);
388+
let place = truncate_projections_for_capture(place, capture_info.capture_kind);
389389

390390
let min_cap_list = match root_var_min_capture_list.get_mut(&var_hir_id) {
391391
None => {
@@ -933,7 +933,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
933933
/// - No Index projections are captured, since arrays are captured completely.
934934
fn truncate_projections_for_capture<'tcx>(
935935
mut place: Place<'tcx>,
936-
capture_clause: hir::CaptureBy,
936+
capture_kind: ty::UpvarCapture<'tcx>,
937937
) -> Place<'tcx> {
938938
if place.projections.is_empty() {
939939
// Nothing to do here
@@ -948,7 +948,7 @@ fn truncate_projections_for_capture<'tcx>(
948948
let mut first_index_projection = None;
949949
let mut first_deref_projection = None;
950950
let mut first_raw_ptr = None;
951-
let mut last_field_projection = None;
951+
//let mut last_field_projection = None;
952952

953953
for (i, proj) in place.projections.iter().enumerate() {
954954
if proj.ty.is_unsafe_ptr() {
@@ -968,7 +968,7 @@ fn truncate_projections_for_capture<'tcx>(
968968
first_deref_projection.get_or_insert(i);
969969
}
970970
ProjectionKind::Field(..) => {
971-
last_field_projection = Some(i);
971+
//last_field_projection = Some(i);
972972
}
973973
ProjectionKind::Subslice => {} // We never capture this
974974
}
@@ -983,16 +983,18 @@ fn truncate_projections_for_capture<'tcx>(
983983
length = first_index_projection.map_or(length, |idx| cmp::min(length, idx));
984984

985985
// In case of move closure, don't apply Deref or any further projections
986-
length = match capture_clause {
987-
hir::CaptureBy::Value => first_deref_projection.map_or(length, |idx| cmp::min(length, idx)),
988-
hir::CaptureBy::Ref => length,
986+
length = match capture_kind {
987+
ty::UpvarCapture::ByValue(..) => {
988+
first_deref_projection.map_or(length, |idx| cmp::min(length, idx))
989+
}
990+
ty::UpvarCapture::ByRef(..) => length,
989991
};
990992

991-
if env::var("SG_DROP_DEREFS").is_ok() {
992-
// Since we will only have Field and Deref projections at this point.
993-
// This will truncate trailing derefs.
994-
length = last_field_projection.map_or(length, |idx| cmp::min(length, idx + 1));
995-
}
993+
//if env::var("SG_DROP_DEREFS").is_ok() {
994+
//// Since we will only have Field and Deref projections at this point.
995+
//// This will truncate trailing derefs.
996+
//length = last_field_projection.map_or(length, |idx| cmp::min(length, idx + 1));
997+
//}
996998

997999
place.projections.truncate(length);
9981000

src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@ LL | f();
7070
error[E0382]: borrow of moved value: `x`
7171
--> $DIR/borrowck-closures-slice-patterns.rs:51:5
7272
|
73+
LL | fn arr_box_by_move(x: Box<[String; 3]>) {
74+
| - move occurs because `x` has type `Box<[String; 3]>`, which does not implement the `Copy` trait
7375
LL | let f = || {
7476
| -- value moved into closure here
7577
LL | let [y, z @ ..] = *x;
7678
| -- variable moved due to use in closure
7779
LL | };
7880
LL | &x;
7981
| ^^ value borrowed here after move
80-
|
81-
= note: move occurs because `*x` has type `[String; 3]`, which does not implement the `Copy` trait
8282

8383
error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable
8484
--> $DIR/borrowck-closures-slice-patterns.rs:59:13

0 commit comments

Comments
 (0)