Use ItemLocalId as key for closure_tys and closure_kinds in TypeckTables.

This commit is contained in:
Michael Woerister 2017-08-07 15:50:13 +02:00
parent e777189b4a
commit 454533f5d9
12 changed files with 76 additions and 33 deletions

View file

@ -654,8 +654,8 @@ for ty::TypeckTables<'gcx> {
(hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
});
ich::hash_stable_nodemap(hcx, hasher, closure_tys);
ich::hash_stable_nodemap(hcx, hasher, closure_kinds);
ich::hash_stable_itemlocalmap(hcx, hasher, closure_tys);
ich::hash_stable_itemlocalmap(hcx, hasher, closure_kinds);
ich::hash_stable_nodemap(hcx, hasher, liberated_fn_sigs);
ich::hash_stable_nodemap(hcx, hasher, fru_field_types);
ich::hash_stable_nodemap(hcx, hasher, cast_kinds);

View file

@ -1331,9 +1331,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
{
if let Some(tables) = self.in_progress_tables {
if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
return tables.borrow()
.closure_kinds
.get(&id)
let tables = tables.borrow();
let hir_id = self.tcx.hir.node_to_hir_id(id);
tables.validate_hir_id(hir_id);
return tables.closure_kinds
.get(&hir_id.local_id)
.cloned()
.map(|(kind, _)| kind);
}
@ -1353,7 +1355,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn fn_sig(&self, def_id: DefId) -> ty::PolyFnSig<'tcx> {
if let Some(tables) = self.in_progress_tables {
if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
if let Some(&ty) = tables.borrow().closure_tys.get(&id) {
let tables = tables.borrow();
let hir_id = self.tcx.hir.node_to_hir_id(id);
tables.validate_hir_id(hir_id);
if let Some(&ty) = tables.closure_tys.get(&hir_id.local_id) {
return ty;
}
}

View file

@ -697,6 +697,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
fn_node_id: ast::NodeId)
-> McResult<cmt<'tcx>>
{
let fn_hir_id = self.tcx.hir.node_to_hir_id(fn_node_id);
self.tables.validate_hir_id(fn_hir_id);
// An upvar can have up to 3 components. We translate first to a
// `Categorization::Upvar`, which is itself a fiction -- it represents the reference to the
// field from the environment.
@ -720,7 +723,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
// FnMut | copied -> &'env mut | upvar -> &'env mut -> &'up bk
// FnOnce | copied | upvar -> &'up bk
let kind = match self.tables.closure_kinds.get(&fn_node_id) {
let kind = match self.tables.closure_kinds.get(&fn_hir_id.local_id) {
Some(&(kind, _)) => kind,
None => span_bug!(span, "missing closure kind")
};

View file

@ -682,7 +682,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// Additional context information explaining why the closure only implements
// a particular trait.
if let Some(tables) = self.in_progress_tables {
match tables.borrow().closure_kinds.get(&node_id) {
let tables = tables.borrow();
let closure_hir_id = self.tcx.hir.node_to_hir_id(node_id);
tables.validate_hir_id(closure_hir_id);
match tables.closure_kinds.get(&closure_hir_id.local_id) {
Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) => {
err.span_note(span, &format!(
"closure is `FnOnce` because it moves the \

View file

@ -236,11 +236,11 @@ pub struct TypeckTables<'tcx> {
pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
/// Records the type of each closure.
pub closure_tys: NodeMap<ty::PolyFnSig<'tcx>>,
pub closure_tys: ItemLocalMap<ty::PolyFnSig<'tcx>>,
/// Records the kind of each closure and the span and name of the variable
/// that caused the closure to be this kind.
pub closure_kinds: NodeMap<(ty::ClosureKind, Option<(Span, ast::Name)>)>,
pub closure_kinds: ItemLocalMap<(ty::ClosureKind, Option<(Span, ast::Name)>)>,
/// For each fn, records the "liberated" types of its arguments
/// and return type. Liberated means that all bound regions
@ -283,8 +283,8 @@ impl<'tcx> TypeckTables<'tcx> {
adjustments: ItemLocalMap(),
pat_binding_modes: ItemLocalMap(),
upvar_capture_map: FxHashMap(),
closure_tys: NodeMap(),
closure_kinds: NodeMap(),
closure_tys: ItemLocalMap(),
closure_kinds: ItemLocalMap(),
liberated_fn_sigs: NodeMap(),
fru_field_types: NodeMap(),
cast_kinds: NodeMap(),

View file

@ -598,8 +598,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
let need_note = match lp.ty.sty {
ty::TypeVariants::TyClosure(id, _) => {
let node_id = self.tcx.hir.as_local_node_id(id).unwrap();
let hir_id = self.tcx.hir.node_to_hir_id(node_id);
self.tables.validate_hir_id(hir_id);
if let Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) =
self.tables.closure_kinds.get(&node_id)
self.tables.closure_kinds.get(&hir_id.local_id)
{
err.span_note(span, &format!(
"closure cannot be invoked more than once because \

View file

@ -102,12 +102,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
sig,
opt_kind);
self.tables.borrow_mut().closure_tys.insert(expr.id, sig);
match opt_kind {
Some(kind) => {
self.tables.borrow_mut().closure_kinds.insert(expr.id, (kind, None));
{
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(expr.hir_id);
tables.closure_tys.insert(expr.hir_id.local_id, sig);
match opt_kind {
Some(kind) => {
tables.closure_kinds.insert(expr.hir_id.local_id, (kind, None));
}
None => {}
}
None => {}
}
closure_type

View file

@ -820,7 +820,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
let closure_id = match step.self_ty.sty {
ty::TyClosure(def_id, _) => {
if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
id
self.tcx.hir.node_to_hir_id(id)
} else {
continue;
}
@ -828,11 +828,14 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
_ => continue,
};
let closure_kinds = &self.tables.borrow().closure_kinds;
let closure_kind = match closure_kinds.get(&closure_id) {
Some(&(k, _)) => k,
None => {
return Err(MethodError::ClosureAmbiguity(trait_def_id));
let closure_kind = {
let tables = self.tables.borrow();
tables.validate_hir_id(closure_id);
match tables.closure_kinds.get(&closure_id.local_id) {
Some(&(k, _)) => k,
None => {
return Err(MethodError::ClosureAmbiguity(trait_def_id));
}
}
};

View file

@ -743,7 +743,8 @@ fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> ty::ClosureKind {
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
tcx.typeck_tables_of(def_id).closure_kinds[&node_id].0
let hir_id = tcx.hir.node_to_hir_id(node_id);
tcx.typeck_tables_of(def_id).closure_kinds[&hir_id.local_id].0
}
fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

View file

@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
debug!("analyze_closure(id={:?}, body.id={:?})", id, body.id());
let infer_kind = match self.tables.borrow_mut().closure_kinds.entry(id) {
let infer_kind = match self.tables.borrow_mut().closure_kinds.entry(hir_id.local_id) {
Entry::Occupied(_) => false,
Entry::Vacant(entry) => {
debug!("check_closure: adding closure {:?} as Fn", id);
@ -152,7 +152,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Write the adjusted values back into the main tables.
if infer_kind {
if let Some(kind) = delegate.adjust_closure_kinds.remove(&id) {
self.tables.borrow_mut().closure_kinds.insert(id, kind);
self.tables.borrow_mut().closure_kinds.insert(hir_id.local_id, kind);
}
}
self.tables.borrow_mut().upvar_capture_map.extend(
@ -468,7 +468,13 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
closure_id, new_kind, upvar_span, var_name);
let closure_kind = self.adjust_closure_kinds.get(&closure_id).cloned()
.or_else(|| self.fcx.tables.borrow().closure_kinds.get(&closure_id).cloned());
.or_else(|| {
let closure_id = self.fcx.tcx.hir.node_to_hir_id(closure_id);
let fcx_tables = self.fcx.tables.borrow();
fcx_tables.validate_hir_id(closure_id);
fcx_tables.closure_kinds.get(&closure_id.local_id).cloned()
});
if let Some((existing_kind, _)) = closure_kind {
debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}",
closure_id, existing_kind, new_kind);

View file

@ -230,12 +230,19 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}
fn visit_closures(&mut self) {
for (&id, closure_ty) in self.fcx.tables.borrow().closure_tys.iter() {
let closure_ty = self.resolve(closure_ty, &id);
let fcx_tables = self.fcx.tables.borrow();
debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
for (&id, closure_ty) in fcx_tables.closure_tys.iter() {
let hir_id = hir::HirId {
owner: fcx_tables.local_id_root.index,
local_id: id,
};
let closure_ty = self.resolve(closure_ty, &hir_id);
self.tables.closure_tys.insert(id, closure_ty);
}
for (&id, &closure_kind) in self.fcx.tables.borrow().closure_kinds.iter() {
for (&id, &closure_kind) in fcx_tables.closure_kinds.iter() {
self.tables.closure_kinds.insert(id, closure_kind);
}
}
@ -380,6 +387,13 @@ impl Locatable for ast::NodeId {
fn to_span(&self, tcx: &TyCtxt) -> Span { tcx.hir.span(*self) }
}
impl Locatable for hir::HirId {
fn to_span(&self, tcx: &TyCtxt) -> Span {
let node_id = tcx.hir.definitions().find_node_for_hir_id(*self);
tcx.hir.span(node_id)
}
}
///////////////////////////////////////////////////////////////////////////
// The Resolver. This is the type folding engine that detects
// unresolved types and so forth.

View file

@ -1239,8 +1239,10 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
))
}
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
tcx.typeck_tables_of(def_id).closure_tys[&node_id]
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), hir_id, .. }) => {
let tables = tcx.typeck_tables_of(def_id);
tables.validate_hir_id(hir_id);
tables.closure_tys[&hir_id.local_id]
}
x => {