Skip to content

Commit f46a757

Browse files
authored
Rollup merge of rust-lang#56906 - blitzerr:master, r=nikomatsakis
Issue rust-lang#56905 Adding a map to TypeckTables to get the list of all the Upvars given a closureID. This is help us get rid of the recurring pattern in the codebase of iterating over the free vars using with_freevars.
2 parents e801ffa + d751954 commit f46a757

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

src/librustc/ty/context.rs

+10
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,12 @@ pub struct TypeckTables<'tcx> {
434434
/// All the existential types that are restricted to concrete types
435435
/// by this function
436436
pub concrete_existential_types: FxHashMap<DefId, Ty<'tcx>>,
437+
438+
/// Given the closure ID this map provides the list of UpvarIDs used by it.
439+
/// The upvarID contains the HIR node ID and it also contains the full path
440+
/// leading to the member of the struct or tuple that is used instead of the
441+
/// entire variable.
442+
pub upvar_list: ty::UpvarListMap<'tcx>,
437443
}
438444

439445
impl<'tcx> TypeckTables<'tcx> {
@@ -459,6 +465,7 @@ impl<'tcx> TypeckTables<'tcx> {
459465
tainted_by_errors: false,
460466
free_region_map: Default::default(),
461467
concrete_existential_types: Default::default(),
468+
upvar_list: Default::default(),
462469
}
463470
}
464471

@@ -768,6 +775,8 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
768775
tainted_by_errors,
769776
ref free_region_map,
770777
ref concrete_existential_types,
778+
ref upvar_list,
779+
771780
} = *self;
772781

773782
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
@@ -811,6 +820,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
811820
tainted_by_errors.hash_stable(hcx, hasher);
812821
free_region_map.hash_stable(hcx, hasher);
813822
concrete_existential_types.hash_stable(hcx, hasher);
823+
upvar_list.hash_stable(hcx, hasher);
814824
})
815825
}
816826
}

src/librustc/ty/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,8 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::TyS<'gcx> {
598598

599599
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
600600

601+
pub type UpvarListMap<'tcx> = FxHashMap<DefId, Vec<UpvarId>>;
602+
601603
impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {}
602604
impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {}
603605

src/librustc_typeck/check/upvar.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
132132
};
133133

134134
self.tcx.with_freevars(closure_node_id, |freevars| {
135+
let mut freevar_list: Vec<ty::UpvarId> = Vec::with_capacity(freevars.len());
135136
for freevar in freevars {
136137
let upvar_id = ty::UpvarId {
137138
var_path: ty::UpvarPath {
138-
hir_id : self.tcx.hir().node_to_hir_id(freevar.var_id()),
139+
hir_id: self.tcx.hir().node_to_hir_id(freevar.var_id()),
139140
},
140141
closure_expr_id: LocalDefId::from_def_id(closure_def_id),
141142
};
142143
debug!("seed upvar_id {:?}", upvar_id);
144+
// Adding the upvar Id to the list of Upvars, which will be added
145+
// to the map for the closure at the end of the for loop.
146+
freevar_list.push(upvar_id);
143147

144148
let capture_kind = match capture_clause {
145149
hir::CaptureByValue => ty::UpvarCapture::ByValue,
@@ -159,6 +163,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
159163
.upvar_capture_map
160164
.insert(upvar_id, capture_kind);
161165
}
166+
// Add the vector of freevars to the map keyed with the closure id.
167+
// This gives us an easier access to them without having to call
168+
// with_freevars again..
169+
self.tables
170+
.borrow_mut()
171+
.upvar_list
172+
.insert(closure_def_id, freevar_list);
162173
});
163174

164175
let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
@@ -176,7 +187,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
176187
self.param_env,
177188
region_scope_tree,
178189
&self.tables.borrow(),
179-
).consume_body(body);
190+
)
191+
.consume_body(body);
180192

181193
if let Some(closure_substs) = infer_kind {
182194
// Unify the (as yet unbound) type variable in the closure
@@ -250,9 +262,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
250262
let var_hir_id = tcx.hir().node_to_hir_id(var_node_id);
251263
let freevar_ty = self.node_ty(var_hir_id);
252264
let upvar_id = ty::UpvarId {
253-
var_path: ty::UpvarPath {
254-
hir_id: var_hir_id,
255-
},
265+
var_path: ty::UpvarPath { hir_id: var_hir_id },
256266
closure_expr_id: LocalDefId::from_def_id(closure_def_index),
257267
};
258268
let capture = self.tables.borrow().upvar_capture(upvar_id);
@@ -272,7 +282,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
272282
},
273283
),
274284
}
275-
}).collect()
285+
})
286+
.collect()
276287
})
277288
}
278289
}

0 commit comments

Comments
 (0)