Skip to content

Commit 76c68aa

Browse files
arora-amanjenniferwillslogmosier
committed
Writeback min_capture map to TypeckResults
- Derive TypeFoldable on `hir::place::Place` and associated structs, to them to be written into typeck results. Co-authored-by: Jennifer Wills <wills.jenniferg@gmail.com> Co-authored-by: Logan Mosier <logmosier@gmail.com>
1 parent 15eaa00 commit 76c68aa

File tree

4 files changed

+94
-64
lines changed

4 files changed

+94
-64
lines changed

compiler/rustc_middle/src/hir/place.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,18 @@ use crate::ty::Ty;
44
use rustc_hir::HirId;
55
use rustc_target::abi::VariantIdx;
66

7-
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
7+
#[derive(
8+
Clone,
9+
Copy,
10+
Debug,
11+
PartialEq,
12+
Eq,
13+
Hash,
14+
TyEncodable,
15+
TyDecodable,
16+
TypeFoldable,
17+
HashStable
18+
)]
819
pub enum PlaceBase {
920
/// A temporary variable
1021
Rvalue,
@@ -16,7 +27,18 @@ pub enum PlaceBase {
1627
Upvar(ty::UpvarId),
1728
}
1829

19-
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
30+
#[derive(
31+
Clone,
32+
Copy,
33+
Debug,
34+
PartialEq,
35+
Eq,
36+
Hash,
37+
TyEncodable,
38+
TyDecodable,
39+
TypeFoldable,
40+
HashStable
41+
)]
2042
pub enum ProjectionKind {
2143
/// A dereference of a pointer, reference or `Box<T>` of the given type
2244
Deref,
@@ -36,7 +58,18 @@ pub enum ProjectionKind {
3658
Subslice,
3759
}
3860

39-
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
61+
#[derive(
62+
Clone,
63+
Copy,
64+
Debug,
65+
PartialEq,
66+
Eq,
67+
Hash,
68+
TyEncodable,
69+
TyDecodable,
70+
TypeFoldable,
71+
HashStable
72+
)]
4073
pub struct Projection<'tcx> {
4174
/// Type after the projection is being applied.
4275
pub ty: Ty<'tcx>,
@@ -48,7 +81,7 @@ pub struct Projection<'tcx> {
4881
/// A `Place` represents how a value is located in memory.
4982
///
5083
/// This is an HIR version of `mir::Place`
51-
#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
84+
#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
5285
pub struct Place<'tcx> {
5386
/// The type of the `PlaceBase`
5487
pub base_ty: Ty<'tcx>,
@@ -61,7 +94,7 @@ pub struct Place<'tcx> {
6194
/// A `PlaceWithHirId` represents how a value is located in memory.
6295
///
6396
/// This is an HIR version of `mir::Place`
64-
#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
97+
#[derive(Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
6598
pub struct PlaceWithHirId<'tcx> {
6699
/// `HirId` of the expression or pattern producing this value.
67100
pub hir_id: HirId,

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -672,15 +672,26 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TyS<'tcx> {
672672
#[rustc_diagnostic_item = "Ty"]
673673
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
674674

675-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
675+
#[derive(
676+
Clone,
677+
Copy,
678+
Debug,
679+
PartialEq,
680+
Eq,
681+
Hash,
682+
TyEncodable,
683+
TyDecodable,
684+
TypeFoldable,
685+
HashStable
686+
)]
676687
pub struct UpvarPath {
677688
pub hir_id: hir::HirId,
678689
}
679690

680691
/// Upvars do not get their own `NodeId`. Instead, we use the pair of
681692
/// the original var ID (that is, the root variable that is referenced
682693
/// by the upvar) and the ID of the closure expression.
683-
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
694+
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
684695
pub struct UpvarId {
685696
pub var_path: UpvarPath,
686697
pub closure_expr_id: LocalDefId,
@@ -692,7 +703,7 @@ impl UpvarId {
692703
}
693704
}
694705

695-
#[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, Copy, HashStable)]
706+
#[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, TypeFoldable, Copy, HashStable)]
696707
pub enum BorrowKind {
697708
/// Data must be immutable and is aliasable.
698709
ImmBorrow,
@@ -746,7 +757,7 @@ pub enum BorrowKind {
746757

747758
/// Information describing the capture of an upvar. This is computed
748759
/// during `typeck`, specifically by `regionck`.
749-
#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)]
760+
#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
750761
pub enum UpvarCapture<'tcx> {
751762
/// Upvar is captured by value. This is always true when the
752763
/// closure is labeled `move`, but can also be true in other cases
@@ -763,7 +774,7 @@ pub enum UpvarCapture<'tcx> {
763774
ByRef(UpvarBorrow<'tcx>),
764775
}
765776

766-
#[derive(PartialEq, Clone, Copy, TyEncodable, TyDecodable, HashStable)]
777+
#[derive(PartialEq, Clone, Copy, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
767778
pub struct UpvarBorrow<'tcx> {
768779
/// The kind of borrow: by-ref upvars have access to shared
769780
/// immutable borrows, which are not part of the normal language
@@ -790,7 +801,7 @@ pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<hir::HirId, MinCaptureLis
790801
pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>;
791802

792803
/// A `Place` and the corresponding `CaptureInfo`.
793-
#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
804+
#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
794805
pub struct CapturedPlace<'tcx> {
795806
pub place: HirPlace<'tcx>,
796807
pub info: CaptureInfo<'tcx>,
@@ -799,7 +810,7 @@ pub struct CapturedPlace<'tcx> {
799810
/// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)
800811
/// for a particular capture as well as identifying the part of the source code
801812
/// that triggered this capture to occur.
802-
#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)]
813+
#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, TypeFoldable, HashStable)]
803814
pub struct CaptureInfo<'tcx> {
804815
/// Expr Id pointing to use that resulted in selecting the current capture kind
805816
///

compiler/rustc_typeck/src/check/writeback.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5555
hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => (),
5656
}
5757
wbcx.visit_body(body);
58+
wbcx.visit_min_capture_map();
5859
wbcx.visit_upvar_capture_map();
5960
wbcx.visit_closures();
6061
wbcx.visit_liberated_fn_sigs();
@@ -331,6 +332,37 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
331332
}
332333

333334
impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
335+
fn visit_min_capture_map(&mut self) {
336+
let mut min_captures_wb = ty::MinCaptureInformationMap::with_capacity_and_hasher(
337+
self.fcx.typeck_results.borrow().closure_min_captures.len(),
338+
Default::default(),
339+
);
340+
for (closure_def_id, root_min_captures) in
341+
self.fcx.typeck_results.borrow().closure_min_captures.iter()
342+
{
343+
let mut root_var_map_wb = ty::RootVariableMinCaptureList::with_capacity_and_hasher(
344+
root_min_captures.len(),
345+
Default::default(),
346+
);
347+
for (var_hir_id, min_list) in root_min_captures.iter() {
348+
let min_list_wb = min_list
349+
.iter()
350+
.map(|captured_place| {
351+
let locatable = captured_place.info.expr_id.unwrap_or(
352+
self.tcx().hir().local_def_id_to_hir_id(closure_def_id.expect_local()),
353+
);
354+
355+
self.resolve(captured_place.clone(), &locatable)
356+
})
357+
.collect();
358+
root_var_map_wb.insert(*var_hir_id, min_list_wb);
359+
}
360+
min_captures_wb.insert(*closure_def_id, root_var_map_wb);
361+
}
362+
363+
self.typeck_results.closure_min_captures = min_captures_wb;
364+
}
365+
334366
fn visit_upvar_capture_map(&mut self) {
335367
for (upvar_id, upvar_capture) in self.fcx.typeck_results.borrow().upvar_capture_map.iter() {
336368
let new_upvar_capture = match *upvar_capture {

compiler/rustc_typeck/src/expr_use_visitor.rs

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use rustc_index::vec::Idx;
1515
use rustc_infer::infer::InferCtxt;
1616
use rustc_middle::hir::place::ProjectionKind;
1717
use rustc_middle::ty::{self, adjustment, TyCtxt};
18-
use rustc_span::Span;
1918
use rustc_target::abi::VariantIdx;
2019

2120
use crate::mem_categorization as mc;
@@ -571,38 +570,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
571570
}));
572571
}
573572

574-
/// Walk closure captures but using `closure_caputes` instead
575-
/// of `closure_min_captures`.
576-
///
577-
/// This is needed because clippy uses `ExprUseVisitor` after TypeckResults
578-
/// are written back. We don't currently writeback min_captures to
579-
/// TypeckResults.
580-
fn walk_captures_closure_captures(&mut self, closure_expr: &hir::Expr<'_>) {
581-
// FIXME(arora-aman): Remove this function once rust-lang/project-rfc-2229#18
582-
// is completed.
583-
debug!("walk_captures_closure_captures({:?}), ", closure_expr);
584-
585-
let closure_def_id = self.tcx().hir().local_def_id(closure_expr.hir_id).to_def_id();
586-
let cl_span = self.tcx().hir().span(closure_expr.hir_id);
587-
588-
let captures = &self.mc.typeck_results.closure_captures[&closure_def_id];
589-
590-
for (&var_id, &upvar_id) in captures {
591-
let upvar_capture = self.mc.typeck_results.upvar_capture(upvar_id);
592-
let captured_place =
593-
return_if_err!(self.cat_captured_var(closure_expr.hir_id, cl_span, var_id));
594-
match upvar_capture {
595-
ty::UpvarCapture::ByValue(_) => {
596-
let mode = copy_or_move(&self.mc, &captured_place);
597-
self.delegate.consume(&captured_place, captured_place.hir_id, mode);
598-
}
599-
ty::UpvarCapture::ByRef(upvar_borrow) => {
600-
self.delegate.borrow(&captured_place, captured_place.hir_id, upvar_borrow.kind);
601-
}
602-
}
603-
}
604-
}
605-
606573
/// Handle the case where the current body contains a closure.
607574
///
608575
/// When the current body being handled is a closure, then we must make sure that
@@ -646,16 +613,18 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
646613
let place = &captured_place.place;
647614
let capture_info = captured_place.info;
648615

649-
let upvar_id = if body_owner_is_closure {
616+
let place_base = if body_owner_is_closure {
650617
// Mark the place to be captured by the enclosing closure
651-
ty::UpvarId::new(*var_hir_id, self.body_owner)
618+
PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.body_owner))
652619
} else {
653-
ty::UpvarId::new(*var_hir_id, closure_def_id.expect_local())
620+
// If the body owner isn't a closure then the variable must
621+
// be a local variable
622+
PlaceBase::Local(*var_hir_id)
654623
};
655624
let place_with_id = PlaceWithHirId::new(
656625
capture_info.expr_id.unwrap_or(closure_expr.hir_id),
657626
place.base_ty,
658-
PlaceBase::Upvar(upvar_id),
627+
place_base,
659628
place.projections.clone(),
660629
);
661630

@@ -674,23 +643,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
674643
}
675644
}
676645
}
677-
} else if self.mc.typeck_results.closure_captures.contains_key(&closure_def_id) {
678-
// Handle the case where clippy calls ExprUseVisitor after
679-
self.walk_captures_closure_captures(closure_expr)
680646
}
681647
}
682-
683-
fn cat_captured_var(
684-
&mut self,
685-
closure_hir_id: hir::HirId,
686-
closure_span: Span,
687-
var_id: hir::HirId,
688-
) -> mc::McResult<PlaceWithHirId<'tcx>> {
689-
// Create the place for the variable being borrowed, from the
690-
// perspective of the creator (parent) of the closure.
691-
let var_ty = self.mc.node_ty(var_id)?;
692-
self.mc.cat_res(closure_hir_id, closure_span, var_ty, Res::Local(var_id))
693-
}
694648
}
695649

696650
fn copy_or_move<'a, 'tcx>(

0 commit comments

Comments
 (0)