Skip to content

Commit c55db23

Browse files
committed
Cleanup and code comments
1 parent c4f28ca commit c55db23

File tree

1 file changed

+39
-34
lines changed

1 file changed

+39
-34
lines changed

compiler/rustc_typeck/src/check/upvar.rs

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
148148
fcx: self,
149149
closure_def_id,
150150
closure_span: span,
151-
capture_clause,
152-
_current_closure_kind: ty::ClosureKind::LATTICE_BOTTOM,
153-
_current_origin: None,
154151
capture_information: Default::default(),
155152
fake_reads: Default::default(),
156153
};
@@ -309,6 +306,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
309306
.collect()
310307
}
311308

309+
/// Adjusts the closure capture information to ensure that the operations aren't unasfe,
310+
/// and that the path can be captured with required capture kind (depending on use in closure,
311+
/// move closure etc.)
312+
///
313+
/// Returns the set of of adjusted information along with the inferred closure kind and span
314+
/// associated with the closure kind inference.
315+
///
316+
/// Note that we *always* infer a minimal kind, even if
317+
/// we don't always *use* that in the final result (i.e., sometimes
318+
/// we've taken the closure kind from the expectations instead, and
319+
/// for generators we don't even implement the closure traits
320+
/// really).
321+
///
322+
/// If we inferred that the closure needs to be FnMut/FnOnce, last element of the returned tuplle
323+
/// contains a `Some()` with the `Place` that caused us to do so.
312324
fn process_collected_capture_information(
313325
&self,
314326
capture_clause: hir::CaptureBy,
@@ -320,7 +332,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
320332
let mut origin: Option<(Span, Place<'tcx>)> = None;
321333

322334
for (place, mut capture_info) in capture_information.into_iter() {
323-
let place = restrict_capture_precision(capture_clause, place);
335+
// Apply rules for safety before inferring closure kind
336+
let place = restrict_capture_precision(place);
337+
324338
let usage_span = if let Some(usage_expr) = capture_info.path_expr_id {
325339
self.tcx.hir().span(usage_expr)
326340
} else {
@@ -356,8 +370,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
356370
origin = updated.1;
357371

358372
let (place, capture_kind) = match capture_clause {
359-
hir::CaptureBy::Value => process_for_move(place, capture_info.capture_kind),
360-
hir::CaptureBy::Ref => process_for_ref(place, capture_info.capture_kind),
373+
hir::CaptureBy::Value => adjust_for_move_closure(place, capture_info.capture_kind),
374+
hir::CaptureBy::Ref => {
375+
adjust_for_non_move_closure(place, capture_info.capture_kind)
376+
}
361377
};
362378

363379
capture_info.capture_kind = capture_kind;
@@ -1386,20 +1402,6 @@ struct InferBorrowKind<'a, 'tcx> {
13861402

13871403
closure_span: Span,
13881404

1389-
capture_clause: hir::CaptureBy,
1390-
1391-
// The kind that we have inferred that the current closure
1392-
// requires. Note that we *always* infer a minimal kind, even if
1393-
// we don't always *use* that in the final result (i.e., sometimes
1394-
// we've taken the closure kind from the expectations instead, and
1395-
// for generators we don't even implement the closure traits
1396-
// really).
1397-
_current_closure_kind: ty::ClosureKind,
1398-
1399-
// If we modified `current_closure_kind`, this field contains a `Some()` with the
1400-
// variable access that caused us to do so.
1401-
_current_origin: Option<(Span, Place<'tcx>)>,
1402-
14031405
/// For each Place that is captured by the closure, we track the minimal kind of
14041406
/// access we need (ref, ref mut, move, etc) and the expression that resulted in such access.
14051407
///
@@ -1442,7 +1444,8 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
14421444
place_with_id, diag_expr_id, mode
14431445
);
14441446

1445-
// AMAN: Don't upgrade copy types to ByValue
1447+
// Copy type being used as ByValue are equivalent to ImmBorrow and don't require any
1448+
// escalation.
14461449
match mode {
14471450
euv::ConsumeMode::Copy => return,
14481451
euv::ConsumeMode::Move => {}
@@ -1589,8 +1592,8 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
15891592
if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base {
15901593
assert_eq!(self.closure_def_id.expect_local(), upvar_id.closure_expr_id);
15911594

1592-
// AMAN: Always initialize to ImmBorrow
1593-
// We will increase the CaptureKind in process_collected_capture_information.
1595+
// Initialize to ImmBorrow
1596+
// We will escalate the CaptureKind based on any uses we see or in `process_collected_capture_information`.
15941597
let origin = UpvarRegion(upvar_id, self.closure_span);
15951598
let upvar_region = self.fcx.next_region_var(origin);
15961599
let upvar_borrow = ty::UpvarBorrow { kind: ty::ImmBorrow, region: upvar_region };
@@ -1617,7 +1620,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
16171620
if let PlaceBase::Upvar(_) = place.base {
16181621
// We need to restrict Fake Read precision to avoid fake reading unsafe code,
16191622
// such as deref of a raw pointer.
1620-
let place = restrict_capture_precision(self.capture_clause, place);
1623+
let place = restrict_capture_precision(place);
16211624
let place =
16221625
restrict_repr_packed_field_ref_capture(self.fcx.tcx, self.fcx.param_env, &place);
16231626
self.fake_reads.push((place, cause, diag_expr_id));
@@ -1659,7 +1662,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
16591662
);
16601663

16611664
// We only want repr packed restriction to be applied to reading references into a packed
1662-
// struct, and not when the data is being moved. There for we call this method here instead
1665+
// struct, and not when the data is being moved. Therefore we call this method here instead
16631666
// of in `restrict_capture_precision`.
16641667
let place = restrict_repr_packed_field_ref_capture(
16651668
self.fcx.tcx,
@@ -1697,10 +1700,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
16971700
/// - No projections are applied to raw pointers, since these require unsafe blocks. We capture
16981701
/// them completely.
16991702
/// - No Index projections are captured, since arrays are captured completely.
1700-
fn restrict_capture_precision<'tcx>(
1701-
_capture_clause: hir::CaptureBy,
1702-
mut place: Place<'tcx>,
1703-
) -> Place<'tcx> {
1703+
fn restrict_capture_precision<'tcx>(mut place: Place<'tcx>) -> Place<'tcx> {
17041704
if place.projections.is_empty() {
17051705
// Nothing to do here
17061706
return place;
@@ -1738,19 +1738,22 @@ fn restrict_capture_precision<'tcx>(
17381738
place
17391739
}
17401740

1741-
fn process_for_move<'tcx>(
1741+
/// Take ownership if data being accessed is owned by the variable used to access it
1742+
/// (or if closure attempts to move data that it doesn’t own).
1743+
/// Note: When taking ownership, only capture data found on the stack.
1744+
fn adjust_for_move_closure<'tcx>(
17421745
mut place: Place<'tcx>,
17431746
kind: ty::UpvarCapture<'tcx>,
17441747
) -> (Place<'tcx>, ty::UpvarCapture<'tcx>) {
17451748
let contains_deref_of_ref = place.deref_tys().any(|ty| ty.is_ref());
1749+
let first_deref = place.projections.iter().position(|proj| proj.kind == ProjectionKind::Deref);
1750+
17461751
match kind {
17471752
ty::UpvarCapture::ByRef(..) if contains_deref_of_ref => (place, kind),
17481753

17491754
// If there's any Deref and the data needs to be moved into the closure body,
17501755
// or it's a Deref of a Box, truncate the path to the first deref
1751-
_ if place.deref_tys().next().is_some() => {
1752-
let first_deref =
1753-
place.projections.iter().position(|proj| proj.kind == ProjectionKind::Deref);
1756+
_ if first_deref.is_some() => {
17541757
let place = match first_deref {
17551758
Some(idx) => {
17561759
place.projections.truncate(idx);
@@ -1768,7 +1771,9 @@ fn process_for_move<'tcx>(
17681771
}
17691772
}
17701773

1771-
fn process_for_ref<'tcx>(
1774+
/// Adjust closure capture just that if taking ownership of data, only move data
1775+
/// from enclosing stack frame.
1776+
fn adjust_for_non_move_closure<'tcx>(
17721777
mut place: Place<'tcx>,
17731778
kind: ty::UpvarCapture<'tcx>,
17741779
) -> (Place<'tcx>, ty::UpvarCapture<'tcx>) {

0 commit comments

Comments
 (0)