-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2229: Capture box completely in move closures #86445
Conversation
@@ -1630,7 +1630,14 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { | |||
self.fcx.param_env, | |||
&place_with_id.place, | |||
); | |||
|
|||
let place = restrict_preicision_for_box(&place, self.capture_clause); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let place = restrict_preicision_for_box(&place, self.capture_clause); | |
let place = restrict_precision_for_box(&place, self.capture_clause); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a litle bit surprised, though, to see this call here, in borrow
. Doesn't this apply no matter what type of access we have, so long as we are in a move closure? I think I would expect some common helper routine invoked by consume
and borrow
to do this (along with other forms of "restrict").
// 2. One motivatiton for the user to use a box might be to reduce the amount of data that gets | ||
// moved (if size of pointer < size of data). We want to make sure that this optimization that | ||
// the user made is respected. | ||
fn restrict_preicision_for_box(place: &Place<'tcx>, capture_by: hir::CaptureBy) -> Place<'tcx> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn restrict_preicision_for_box(place: &Place<'tcx>, capture_by: hir::CaptureBy) -> Place<'tcx> { | |
fn restrict_precision_for_box(place: &Place<'tcx>, capture_by: hir::CaptureBy) -> Place<'tcx> { |
@@ -1654,6 +1661,34 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { | |||
} | |||
} | |||
|
|||
// In case of move closures we don't want to capture derefs on a box. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// In case of move closures we don't want to capture derefs on a box. | |
// In the case of move closures, we don't want to capture derefs on a box. |
// In case of move closures we don't want to capture derefs on a box. | ||
// This is motivated by: | ||
// 1. We only want to capture data that is on the stack | ||
// 2. One motivatiton for the user to use a box might be to reduce the amount of data that gets |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 2. One motivatiton for the user to use a box might be to reduce the amount of data that gets | |
// 2. One motivation for the user to use a box might be to reduce the amount of data that gets |
// moved (if size of pointer < size of data). We want to make sure that this optimization that | ||
// the user made is respected. | ||
fn restrict_preicision_for_box(place: &Place<'tcx>, capture_by: hir::CaptureBy) -> Place<'tcx> { | ||
let mut rv = place.clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let mut rv = place.clone(); |
fn restrict_preicision_for_box(place: &Place<'tcx>, capture_by: hir::CaptureBy) -> Place<'tcx> { | ||
let mut rv = place.clone(); | ||
match capture_by { | ||
hir::CaptureBy::Ref => rv, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hir::CaptureBy::Ref => rv, | |
hir::CaptureBy::Ref => place.clone(), |
hir::CaptureBy::Ref => rv, | ||
hir::CaptureBy::Value => { | ||
if ty::TyS::is_box(place.base_ty) { | ||
Place { projections: Vec::new(), ..rv } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Place { projections: Vec::new(), ..rv } | |
Place { projections: Vec::new(), ..place.clone() } |
// In either case we want to stop at the box. | ||
let pos = place.projections.iter().position(|proj| ty::TyS::is_box(proj.ty)); | ||
match pos { | ||
None => rv, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None => rv, | |
None => place.clone(), |
match pos { | ||
None => rv, | ||
Some(idx) => { | ||
Place { projections: rv.projections.drain(0..=idx).collect(), ..rv } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Place { projections: rv.projections.drain(0..=idx).collect(), ..rv } | |
let mut rv = place.clone(); | |
Place { projections: rv.projections.drain(0..=idx).collect(), ..rv } |
This could be more efficient, but good enough I guess.
@bors r+ |
📌 Commit 757add16b06fbd8088d8ff5f85505f780f58e4fb has been approved by |
☔ The latest upstream changes (presumably #86588) made this pull request unmergeable. Please resolve the merge conflicts. |
Even if the content from box is used in a sharef-ref context, we capture the box entirerly. This is motivated by: 1) We only capture data that is on the stack. 2) Capturing data from within the box might end up moving more data than the user anticipated.
fixup! 2229: Capture box completely in move closures
@nikomatsakis udated |
@bors r=nikomatsakis |
📌 Commit d37a07f has been approved by |
☀️ Test successful - checks-actions |
Even if the content from box is used in a sharef-ref context,
we capture the box entirerly.
This is motivated by:
the user anticipated.
Closes rust-lang/project-rfc-2229#50
r? @nikomatsakis