rustc: remove the index field from Res::Upvar.

This commit is contained in:
Eduard-Mihai Burtescu 2019-05-04 05:05:38 +03:00
parent 26e61dd826
commit 4b9670a245
7 changed files with 30 additions and 21 deletions

View File

@ -140,7 +140,6 @@ pub enum Res<Id = hir::HirId> {
SelfCtor(DefId /* impl */), // `DefId` refers to the impl
Local(Id),
Upvar(Id, // `HirId` of closed over local
usize, // index in the `upvars` list of the closure
ast::NodeId), // expr node that creates the closure
// Macro namespace
@ -397,11 +396,7 @@ impl<Id> Res<Id> {
Res::SelfCtor(id) => Res::SelfCtor(id),
Res::PrimTy(id) => Res::PrimTy(id),
Res::Local(id) => Res::Local(map(id)),
Res::Upvar(id, index, closure) => Res::Upvar(
map(id),
index,
closure
),
Res::Upvar(id, closure) => Res::Upvar(map(id), closure),
Res::SelfTy(a, b) => Res::SelfTy(a, b),
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),

View File

@ -2497,9 +2497,8 @@ pub struct Upvar<Id = HirId> {
/// The variable being captured.
pub var_id: Id,
/// The parent closure, if this is not a direct capture,
/// and the index within that closure's capture list.
pub parent: Option<(ast::NodeId, usize)>,
/// The parent closure, if this is not a direct capture.
pub parent: Option<ast::NodeId>,
// First span where it is accessed (there can be multiple).
pub span: Span

View File

@ -964,7 +964,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
let var_ty = self.mc.node_ty(upvar.var_id)?;
let res = upvar.parent.map_or(
Res::Local(upvar.var_id),
|(closure_node_id, i)| Res::Upvar(upvar.var_id, i, closure_node_id),
|closure_node_id| Res::Upvar(upvar.var_id, closure_node_id),
);
self.mc.cat_res(closure_hir_id, closure_span, var_ty, res)
}

View File

@ -737,7 +737,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
})
}
Res::Upvar(var_id, _, fn_node_id) => {
Res::Upvar(var_id, fn_node_id) => {
let var_nid = self.tcx.hir().hir_to_node_id(var_id);
self.cat_upvar(hir_id, span, var_nid, fn_node_id)
}

View File

@ -975,7 +975,9 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
match res {
Res::Local(id) => ExprKind::VarRef { id },
Res::Upvar(var_hir_id, index, closure_expr_id) => {
Res::Upvar(var_hir_id, closure_expr_id) => {
let index = cx.upvar_indices[&var_hir_id];
debug!("convert_var(upvar({:?}, {:?}, {:?}))",
var_hir_id,
index,
@ -1190,7 +1192,7 @@ fn capture_upvar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let var_ty = cx.tables().node_type(upvar.var_id);
let upvar_res = upvar.parent.map_or(
Res::Local(upvar.var_id),
|(closure_node_id, i)| Res::Upvar(upvar.var_id, i, closure_node_id),
|closure_node_id| Res::Upvar(upvar.var_id, closure_node_id),
);
let captured_var = Expr {
temp_lifetime,

View File

@ -5,6 +5,7 @@
use crate::hair::*;
use crate::hair::util::UserAnnotatedTyHelpers;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
use rustc::hir::def_id::DefId;
use rustc::hir::Node;
@ -46,6 +47,9 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
/// See field with the same name on `mir::Body`.
control_flow_destroyed: Vec<(Span, String)>,
/// Reverse map, from upvar variable `HirId`s to their indices.
upvar_indices: FxHashMap<hir::HirId, usize>,
}
impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
@ -53,6 +57,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
src_id: hir::HirId) -> Cx<'a, 'gcx, 'tcx> {
let tcx = infcx.tcx;
let src_def_id = tcx.hir().local_def_id_from_hir_id(src_id);
let tables = tcx.typeck_tables_of(src_def_id);
let body_owner_kind = tcx.hir().body_owner_kind_by_hir_id(src_id);
let constness = match body_owner_kind {
@ -75,6 +80,14 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
// Constants always need overflow checks.
check_overflow |= constness == hir::Constness::Const;
// Compute reverse mapping, of uvpars to their indices.
let mut upvar_indices = FxHashMap::default();
if let Some(upvars) = tables.upvar_list.get(&src_def_id) {
upvar_indices.extend(
upvars.iter().enumerate().map(|(i, upvar_id)| (upvar_id.var_path.hir_id, i)),
);
}
Cx {
tcx,
infcx,
@ -82,11 +95,12 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
param_env: tcx.param_env(src_def_id),
identity_substs: InternalSubsts::identity_for_item(tcx.global_tcx(), src_def_id),
region_scope_tree: tcx.region_scope_tree(src_def_id),
tables: tcx.typeck_tables_of(src_def_id),
tables,
constness,
body_owner_kind,
check_overflow,
control_flow_destroyed: Vec::new(),
upvar_indices,
}
}

View File

@ -1669,7 +1669,7 @@ pub struct Resolver<'a> {
label_res_map: NodeMap<NodeId>,
pub upvars: UpvarMap,
upvars_seen: NodeMap<NodeMap<usize>>,
upvars_seen: NodeMap<NodeSet>,
pub export_map: ExportMap<NodeId>,
pub trait_map: TraitMap,
@ -4052,22 +4052,21 @@ impl<'a> Resolver<'a> {
}
ClosureRibKind(function_id) => {
let parent = match res {
Res::Upvar(_, i, closure) => Some((closure, i)),
Res::Upvar(_, closure) => Some(closure),
_ => None,
};
let seen = self.upvars_seen
.entry(function_id)
.or_default();
if let Some(&index) = seen.get(&var_id) {
res = Res::Upvar(var_id, index, function_id);
if seen.contains(&var_id) {
res = Res::Upvar(var_id, function_id);
continue;
}
let vec = self.upvars
.entry(function_id)
.or_default();
let depth = vec.len();
res = Res::Upvar(var_id, depth, function_id);
res = Res::Upvar(var_id, function_id);
if record_used {
vec.push(Upvar {
@ -4075,7 +4074,7 @@ impl<'a> Resolver<'a> {
parent,
span,
});
seen.insert(var_id, depth);
seen.insert(var_id);
}
}
ItemRibKind | FnItemRibKind | AssocItemRibKind => {