Skip to content

Commit

Permalink
Rollup merge of rust-lang#56906 - blitzerr:master, r=nikomatsakis
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
pietroalbini committed Dec 20, 2018
2 parents e801ffa + d751954 commit f46a757
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
10 changes: 10 additions & 0 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,12 @@ pub struct TypeckTables<'tcx> {
/// All the existential types that are restricted to concrete types
/// by this function
pub concrete_existential_types: FxHashMap<DefId, Ty<'tcx>>,

/// Given the closure ID this map provides the list of UpvarIDs used by it.
/// The upvarID contains the HIR node ID and it also contains the full path
/// leading to the member of the struct or tuple that is used instead of the
/// entire variable.
pub upvar_list: ty::UpvarListMap<'tcx>,
}

impl<'tcx> TypeckTables<'tcx> {
Expand All @@ -459,6 +465,7 @@ impl<'tcx> TypeckTables<'tcx> {
tainted_by_errors: false,
free_region_map: Default::default(),
concrete_existential_types: Default::default(),
upvar_list: Default::default(),
}
}

Expand Down Expand Up @@ -768,6 +775,8 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
tainted_by_errors,
ref free_region_map,
ref concrete_existential_types,
ref upvar_list,

} = *self;

hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
Expand Down Expand Up @@ -811,6 +820,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
tainted_by_errors.hash_stable(hcx, hasher);
free_region_map.hash_stable(hcx, hasher);
concrete_existential_types.hash_stable(hcx, hasher);
upvar_list.hash_stable(hcx, hasher);
})
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,8 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::TyS<'gcx> {

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

pub type UpvarListMap<'tcx> = FxHashMap<DefId, Vec<UpvarId>>;

impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {}
impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {}

Expand Down
23 changes: 17 additions & 6 deletions src/librustc_typeck/check/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};

self.tcx.with_freevars(closure_node_id, |freevars| {
let mut freevar_list: Vec<ty::UpvarId> = Vec::with_capacity(freevars.len());
for freevar in freevars {
let upvar_id = ty::UpvarId {
var_path: ty::UpvarPath {
hir_id : self.tcx.hir().node_to_hir_id(freevar.var_id()),
hir_id: self.tcx.hir().node_to_hir_id(freevar.var_id()),
},
closure_expr_id: LocalDefId::from_def_id(closure_def_id),
};
debug!("seed upvar_id {:?}", upvar_id);
// Adding the upvar Id to the list of Upvars, which will be added
// to the map for the closure at the end of the for loop.
freevar_list.push(upvar_id);

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

let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
Expand All @@ -176,7 +187,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.param_env,
region_scope_tree,
&self.tables.borrow(),
).consume_body(body);
)
.consume_body(body);

if let Some(closure_substs) = infer_kind {
// Unify the (as yet unbound) type variable in the closure
Expand Down Expand Up @@ -250,9 +262,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let var_hir_id = tcx.hir().node_to_hir_id(var_node_id);
let freevar_ty = self.node_ty(var_hir_id);
let upvar_id = ty::UpvarId {
var_path: ty::UpvarPath {
hir_id: var_hir_id,
},
var_path: ty::UpvarPath { hir_id: var_hir_id },
closure_expr_id: LocalDefId::from_def_id(closure_def_index),
};
let capture = self.tables.borrow().upvar_capture(upvar_id);
Expand All @@ -272,7 +282,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
},
),
}
}).collect()
})
.collect()
})
}
}
Expand Down

0 comments on commit f46a757

Please sign in to comment.