Skip to content

Commit 81162b1

Browse files
arora-amanAzhng
andcommitted
Use Places to express closure/generator Captures
Co-authored-by: Archer Zhang <[email protected]>
1 parent 0fb0025 commit 81162b1

File tree

6 files changed

+314
-130
lines changed

6 files changed

+314
-130
lines changed

compiler/rustc_middle/src/ty/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,10 @@ pub struct TypeckResults<'tcx> {
415415
/// entire variable.
416416
pub closure_captures: ty::UpvarListMap,
417417

418+
/// Given the closure ID this map provides the list of
419+
/// `Place`s and how/why are they captured by the closure.
420+
pub closure_capture_information: ty::CaptureInformationMap<'tcx>,
421+
418422
/// Stores the type, expression, span and optional scope span of all types
419423
/// that are live across the yield of this generator (if a generator).
420424
pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
@@ -442,6 +446,7 @@ impl<'tcx> TypeckResults<'tcx> {
442446
tainted_by_errors: None,
443447
concrete_opaque_types: Default::default(),
444448
closure_captures: Default::default(),
449+
closure_capture_information: Default::default(),
445450
generator_interior_types: Default::default(),
446451
}
447452
}
@@ -676,6 +681,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckResults<'tcx> {
676681
tainted_by_errors,
677682
ref concrete_opaque_types,
678683
ref closure_captures,
684+
ref closure_capture_information,
679685
ref generator_interior_types,
680686
} = *self;
681687

@@ -709,6 +715,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckResults<'tcx> {
709715
tainted_by_errors.hash_stable(hcx, hasher);
710716
concrete_opaque_types.hash_stable(hcx, hasher);
711717
closure_captures.hash_stable(hcx, hasher);
718+
closure_capture_information.hash_stable(hcx, hasher);
712719
generator_interior_types.hash_stable(hcx, hasher);
713720
})
714721
}

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub use self::IntVarValue::*;
66
pub use self::Variance::*;
77

88
use crate::hir::exports::ExportMap;
9+
use crate::hir::place::Place as HirPlace;
910
use crate::ich::StableHashingContext;
1011
use crate::middle::cstore::CrateStoreDyn;
1112
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
@@ -674,6 +675,12 @@ pub struct UpvarId {
674675
pub closure_expr_id: LocalDefId,
675676
}
676677

678+
impl UpvarId {
679+
pub fn new(var_hir_id: hir::HirId, closure_def_id: LocalDefId) -> UpvarId {
680+
UpvarId { var_path: UpvarPath { hir_id: var_hir_id }, closure_expr_id: closure_def_id }
681+
}
682+
}
683+
677684
#[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, Copy, HashStable)]
678685
pub enum BorrowKind {
679686
/// Data must be immutable and is aliasable.
@@ -756,9 +763,40 @@ pub struct UpvarBorrow<'tcx> {
756763
pub region: ty::Region<'tcx>,
757764
}
758765

766+
#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)]
767+
pub struct CaptureInfo<'tcx> {
768+
/// Expr Id pointing to use that resulting in selecting the current capture kind
769+
pub expr_id: Option<hir::HirId>,
770+
771+
/// Capture mode that was selected
772+
pub capture_kind: UpvarCapture<'tcx>,
773+
}
774+
759775
pub type UpvarListMap = FxHashMap<DefId, FxIndexMap<hir::HirId, UpvarId>>;
760776
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
761777

778+
/// Consider closure where s.str1 is captured via an ImmutableBorrow and s.str2 via a MutableBorrow
779+
///
780+
/// ```rust
781+
/// // Assume that thte HirId for the variable definition is `V1`
782+
/// let mut s = SomeStruct { str1: format!("s1"), str2: format!("s2") }
783+
///
784+
/// let fix_s = |new_s2| {
785+
/// // Assume that the HirId for the expression `s.str1` is `E1`
786+
/// println!("Updating SomeStruct with str1=", s.str1);
787+
/// // Assume that the HirId for the expression `*s.str2` is `E2`
788+
/// s.str2 = new_s2;
789+
/// }
790+
/// ```
791+
///
792+
/// For closure `fix_s`, (at a high level) the IndexMap will contain:
793+
///
794+
/// Place { V1, [ProjectionKind::Field(Index=0, Variant=0)] } : CaptureKind { E1, ImmutableBorrow }
795+
/// Place { V1, [ProjectionKind::Field(Index=1, Variant=0)] } : CaptureKind { E2, MutableBorrow }
796+
///
797+
pub type CaptureInformationMap<'tcx> =
798+
FxHashMap<DefId, FxIndexMap<HirPlace<'tcx>, CaptureInfo<'tcx>>>;
799+
762800
#[derive(Clone, Copy, PartialEq, Eq)]
763801
pub enum IntVarValue {
764802
IntType(ast::IntTy),

compiler/rustc_mir_build/src/thir/cx/expr.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,9 @@ fn make_mirror_unadjusted<'a, 'tcx>(
387387
}
388388
};
389389
let upvars = cx
390-
.tcx
391-
.upvars_mentioned(def_id)
390+
.typeck_results()
391+
.closure_captures
392+
.get(&def_id)
392393
.iter()
393394
.flat_map(|upvars| upvars.iter())
394395
.zip(substs.upvar_tys())

0 commit comments

Comments
 (0)