Encapsulate sub-table access in TypeckTables and validate keys on each access.

This commit is contained in:
Michael Woerister 2017-08-10 16:10:04 +02:00
parent bdfd78db8a
commit 1f54df1101
31 changed files with 463 additions and 316 deletions

View File

@ -11,8 +11,7 @@
//! This module contains `HashStable` implementations for various data types
//! from rustc::ty in no particular order.
use hir::def_id::DefId;
use ich::{self, StableHashingContext, NodeIdHashingMode};
use ich::StableHashingContext;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult};
use std::hash as std_hash;
@ -612,71 +611,6 @@ impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
ty
});
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
for ty::TypeckTables<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
let ty::TypeckTables {
local_id_root,
ref type_dependent_defs,
ref node_types,
ref node_substs,
ref adjustments,
ref pat_binding_modes,
ref upvar_capture_map,
ref closure_tys,
ref closure_kinds,
ref liberated_fn_sigs,
ref fru_field_types,
ref cast_kinds,
ref used_trait_imports,
tainted_by_errors,
ref free_region_map,
} = *self;
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
ich::hash_stable_itemlocalmap(hcx, hasher, type_dependent_defs);
ich::hash_stable_itemlocalmap(hcx, hasher, node_types);
ich::hash_stable_itemlocalmap(hcx, hasher, node_substs);
ich::hash_stable_itemlocalmap(hcx, hasher, adjustments);
ich::hash_stable_itemlocalmap(hcx, hasher, pat_binding_modes);
ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
let ty::UpvarId {
var_id,
closure_expr_id
} = *up_var_id;
let var_def_id = DefId {
krate: local_id_root.krate,
index: var_id,
};
let closure_def_id = DefId {
krate: local_id_root.krate,
index: closure_expr_id,
};
(hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
});
ich::hash_stable_itemlocalmap(hcx, hasher, closure_tys);
ich::hash_stable_itemlocalmap(hcx, hasher, closure_kinds);
ich::hash_stable_itemlocalmap(hcx, hasher, liberated_fn_sigs);
ich::hash_stable_itemlocalmap(hcx, hasher, fru_field_types);
ich::hash_stable_itemlocalmap(hcx, hasher, cast_kinds);
ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| {
hcx.def_path_hash(*def_id)
});
tainted_by_errors.hash_stable(hcx, hasher);
free_region_map.hash_stable(hcx, hasher);
})
}
}
impl_stable_hash_for!(enum ty::fast_reject::SimplifiedType {
BoolSimplifiedType,
CharSimplifiedType,

View File

@ -1331,11 +1331,10 @@ 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) {
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)
return tables.borrow()
.closure_kinds()
.get(hir_id)
.cloned()
.map(|(kind, _)| kind);
}
@ -1355,10 +1354,8 @@ 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) {
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) {
if let Some(&ty) = tables.borrow().closure_tys().get(hir_id) {
return ty;
}
}

View File

@ -94,8 +94,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}
}
fn lookup_and_handle_method(&mut self, id: hir::ItemLocalId) {
self.check_def_id(self.tables.type_dependent_defs[&id].def_id());
fn lookup_and_handle_method(&mut self, id: hir::HirId) {
self.check_def_id(self.tables.type_dependent_defs()[id].def_id());
}
fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
@ -241,7 +241,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
self.handle_definition(def);
}
hir::ExprMethodCall(..) => {
self.lookup_and_handle_method(expr.hir_id.local_id);
self.lookup_and_handle_method(expr.hir_id);
}
hir::ExprField(ref lhs, ref name) => {
self.handle_field_access(&lhs, name.node);

View File

@ -166,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node {
hir::ExprMethodCall(..) => {
let def_id = self.tables.type_dependent_defs[&expr.hir_id.local_id].def_id();
let def_id = self.tables.type_dependent_defs()[expr.hir_id].def_id();
let sig = self.tcx.fn_sig(def_id);
debug!("effect: method call case, signature is {:?}",
sig);

View File

@ -537,7 +537,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
}
ty::TyError => { }
_ => {
let def_id = self.mc.tables.type_dependent_defs[&call.hir_id.local_id].def_id();
let def_id = self.mc.tables.type_dependent_defs()[call.hir_id].def_id();
match OverloadedCallType::from_method_id(self.tcx(), def_id) {
FnMutOverloadedCall => {
let call_scope_r = self.tcx().node_scope_region(call.id);
@ -797,8 +797,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
pat);
return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |cmt_pat, pat| {
if let PatKind::Binding(..) = pat.node {
self.mc.tables.validate_hir_id(pat.hir_id);
let bm = *self.mc.tables.pat_binding_modes.get(&pat.hir_id.local_id)
let bm = *self.mc.tables.pat_binding_modes().get(pat.hir_id)
.expect("missing binding mode");
match bm {
ty::BindByReference(..) =>
@ -824,8 +823,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
if let PatKind::Binding(_, def_id, ..) = pat.node {
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode);
mc.tables.validate_hir_id(pat.hir_id);
let bm = *mc.tables.pat_binding_modes.get(&pat.hir_id.local_id)
let bm = *mc.tables.pat_binding_modes().get(pat.hir_id)
.expect("missing binding mode");
// pat_ty: the type of the binding being produced.

View File

@ -334,10 +334,8 @@ impl MutabilityCategory {
let ret = match tcx.hir.get(id) {
hir_map::NodeLocal(p) => match p.node {
PatKind::Binding(..) => {
tables.validate_hir_id(p.hir_id);
let bm = *tables.pat_binding_modes
.get(&p.hir_id.local_id)
let bm = *tables.pat_binding_modes()
.get(p.hir_id)
.expect("missing binding mode");
if bm == ty::BindByValue(hir::MutMutable) {
McDeclared
@ -485,10 +483,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
// fundamental fix to this conflated use of the node id.
let ret_ty = match pat.node {
PatKind::Binding(..) => {
self.tables.validate_hir_id(pat.hir_id);
let bm = *self.tables
.pat_binding_modes
.get(&pat.hir_id.local_id)
.pat_binding_modes()
.get(pat.hir_id)
.expect("missing binding mode");
if let ty::BindByReference(_) = bm {
@ -698,7 +695,6 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
-> 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
@ -723,7 +719,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_hir_id.local_id) {
let kind = match self.tables.closure_kinds().get(fn_hir_id) {
Some(&(kind, _)) => kind,
None => span_bug!(span, "missing closure kind")
};

View File

@ -110,7 +110,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
Some(self.tables.qpath_def(qpath, expr.hir_id))
}
hir::ExprMethodCall(..) => {
Some(self.tables.type_dependent_defs[&expr.hir_id.local_id])
Some(self.tables.type_dependent_defs()[expr.hir_id])
}
_ => None
};

View File

@ -684,8 +684,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
if let Some(tables) = self.in_progress_tables {
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) {
match tables.closure_kinds().get(closure_hir_id) {
Some(&(ty::ClosureKind::FnOnce, Some((span, name)))) => {
err.span_note(span, &format!(
"closure is `FnOnce` because it moves the \

View File

@ -20,6 +20,7 @@ use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use hir::map as hir_map;
use hir::map::DefPathHash;
use lint::{self, Lint};
use ich::{self, StableHashingContext, NodeIdHashingMode};
use middle::free_region::FreeRegionMap;
use middle::lang_items;
use middle::resolve_lifetime;
@ -45,19 +46,22 @@ use ty::BindingMode;
use util::nodemap::{NodeMap, NodeSet, DefIdSet, ItemLocalMap};
use util::nodemap::{FxHashMap, FxHashSet};
use rustc_data_structures::accumulate_vec::AccumulateVec;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
StableHasherResult};
use arena::{TypedArena, DroplessArena};
use rustc_data_structures::indexed_vec::IndexVec;
use std::borrow::Borrow;
use std::cell::{Cell, RefCell};
use std::cmp::Ordering;
use std::collections::hash_map::{self, Entry};
use std::hash::{Hash, Hasher};
use std::mem;
use std::ops::Deref;
use std::iter;
use std::rc::Rc;
use syntax::abi;
use syntax::ast::{self, Name};
use syntax::ast::{self, Name, NodeId};
use syntax::attr;
use syntax::codemap::MultiSpan;
use syntax::symbol::{Symbol, keywords};
@ -207,6 +211,91 @@ pub struct CommonTypes<'tcx> {
pub re_erased: Region<'tcx>,
}
pub struct LocalTableInContext<'a, V: 'a> {
local_id_root: DefId,
data: &'a ItemLocalMap<V>
}
/// Validate that the given HirId (respectively its `local_id` part) can be
/// safely used as a key in the tables of a TypeckTable. For that to be
/// the case, the HirId must have the same `owner` as all the other IDs in
/// this table (signified by `local_id_root`). Otherwise the HirId
/// would be in a different frame of reference and using its `local_id`
/// would result in lookup errors, or worse, in silently wrong data being
/// stored/returned.
fn validate_hir_id_for_typeck_tables(table_id_root: DefId, hir_id: hir::HirId) {
#[cfg(debug_assertions)]
{
if table_id_root.is_local() {
if hir_id.owner != table_id_root.index {
ty::tls::with(|tcx| {
let node_id = tcx.hir
.definitions()
.find_node_for_hir_id(hir_id);
bug!("node {} with HirId::owner {:?} cannot be placed in \
TypeckTables with local_id_root {:?}",
tcx.hir.node_to_string(node_id),
DefId::local(hir_id.owner),
table_id_root)
});
}
}
}
}
impl<'a, V> LocalTableInContext<'a, V> {
pub fn contains_key(&self, id: hir::HirId) -> bool {
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.data.contains_key(&id.local_id)
}
pub fn get(&self, id: hir::HirId) -> Option<&V> {
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.data.get(&id.local_id)
}
pub fn iter(&self) -> hash_map::Iter<hir::ItemLocalId, V> {
self.data.iter()
}
}
impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
type Output = V;
fn index(&self, key: hir::HirId) -> &V {
self.get(key).expect("LocalTableInContext: key not found")
}
}
pub struct LocalTableInContextMut<'a, V: 'a> {
local_id_root: DefId,
data: &'a mut ItemLocalMap<V>
}
impl<'a, V> LocalTableInContextMut<'a, V> {
pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> {
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.data.get_mut(&id.local_id)
}
pub fn entry(&mut self, id: hir::HirId) -> Entry<hir::ItemLocalId, V> {
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.data.entry(id.local_id)
}
pub fn insert(&mut self, id: hir::HirId, val: V) -> Option<V> {
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.data.insert(id.local_id, val)
}
pub fn remove(&mut self, id: hir::HirId) -> Option<V> {
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.data.remove(&id.local_id)
}
}
#[derive(RustcEncodable, RustcDecodable)]
pub struct TypeckTables<'tcx> {
/// The HirId::owner all ItemLocalIds in this table are relative to.
@ -214,50 +303,50 @@ pub struct TypeckTables<'tcx> {
/// Resolved definitions for `<T>::X` associated paths and
/// method calls, including those of overloaded operators.
pub type_dependent_defs: ItemLocalMap<Def>,
type_dependent_defs: ItemLocalMap<Def>,
/// Stores the types for various nodes in the AST. Note that this table
/// is not guaranteed to be populated until after typeck. See
/// typeck::check::fn_ctxt for details.
pub node_types: ItemLocalMap<Ty<'tcx>>,
node_types: ItemLocalMap<Ty<'tcx>>,
/// Stores the type parameters which were substituted to obtain the type
/// of this node. This only applies to nodes that refer to entities
/// parameterized by type parameters, such as generic fns, types, or
/// other items.
pub node_substs: ItemLocalMap<&'tcx Substs<'tcx>>,
node_substs: ItemLocalMap<&'tcx Substs<'tcx>>,
pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
// Stores the actual binding mode for all instances of hir::BindingAnnotation.
pub pat_binding_modes: ItemLocalMap<BindingMode>,
pat_binding_modes: ItemLocalMap<BindingMode>,
/// Borrows
pub upvar_capture_map: ty::UpvarCaptureMap<'tcx>,
/// Records the type of each closure.
pub closure_tys: ItemLocalMap<ty::PolyFnSig<'tcx>>,
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: ItemLocalMap<(ty::ClosureKind, Option<(Span, ast::Name)>)>,
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
/// (including late-bound regions) are replaced with free
/// equivalents. This table is not used in trans (since regions
/// are erased there) and hence is not serialized to metadata.
pub liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
liberated_fn_sigs: ItemLocalMap<ty::FnSig<'tcx>>,
/// For each FRU expression, record the normalized types of the fields
/// of the struct - this is needed because it is non-trivial to
/// normalize while preserving regions. This table is used only in
/// MIR construction and hence is not serialized to metadata.
pub fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
fru_field_types: ItemLocalMap<Vec<Ty<'tcx>>>,
/// Maps a cast expression to its kind. This is keyed on the
/// *from* expression of the cast, not the cast itself.
pub cast_kinds: ItemLocalMap<ty::cast::CastKind>,
cast_kinds: ItemLocalMap<ty::cast::CastKind>,
/// Set of trait imports actually used in the method resolution.
/// This is used for warning unused imports.
@ -288,7 +377,6 @@ impl<'tcx> TypeckTables<'tcx> {
liberated_fn_sigs: ItemLocalMap(),
fru_field_types: ItemLocalMap(),
cast_kinds: ItemLocalMap(),
lints: lint::LintTable::new(),
used_trait_imports: DefIdSet(),
tainted_by_errors: false,
free_region_map: FreeRegionMap::new(),
@ -300,12 +388,40 @@ impl<'tcx> TypeckTables<'tcx> {
match *qpath {
hir::QPath::Resolved(_, ref path) => path.def,
hir::QPath::TypeRelative(..) => {
self.validate_hir_id(id);
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.type_dependent_defs.get(&id.local_id).cloned().unwrap_or(Def::Err)
}
}
}
pub fn type_dependent_defs(&self) -> LocalTableInContext<Def> {
LocalTableInContext {
local_id_root: self.local_id_root,
data: &self.type_dependent_defs
}
}
pub fn type_dependent_defs_mut(&mut self) -> LocalTableInContextMut<Def> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.type_dependent_defs
}
}
pub fn node_types(&self) -> LocalTableInContext<Ty<'tcx>> {
LocalTableInContext {
local_id_root: self.local_id_root,
data: &self.node_types
}
}
pub fn node_types_mut(&mut self) -> LocalTableInContextMut<Ty<'tcx>> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.node_types
}
}
pub fn node_id_to_type(&self, id: hir::HirId) -> Ty<'tcx> {
match self.node_id_to_type_opt(id) {
Some(ty) => ty,
@ -320,15 +436,27 @@ impl<'tcx> TypeckTables<'tcx> {
}
pub fn node_id_to_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
self.validate_hir_id(id);
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.node_types.get(&id.local_id).cloned()
}
pub fn node_substs_mut(&mut self) -> LocalTableInContextMut<&'tcx Substs<'tcx>> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.node_substs
}
}
pub fn node_substs(&self, id: hir::HirId) -> &'tcx Substs<'tcx> {
self.validate_hir_id(id);
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.node_substs.get(&id.local_id).cloned().unwrap_or(Substs::empty())
}
pub fn node_substs_opt(&self, id: hir::HirId) -> Option<&'tcx Substs<'tcx>> {
validate_hir_id_for_typeck_tables(self.local_id_root, id);
self.node_substs.get(&id.local_id).cloned()
}
// Returns the type of a pattern as a monotype. Like @expr_ty, this function
// doesn't provide type parameter substitutions.
pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
@ -357,9 +485,24 @@ impl<'tcx> TypeckTables<'tcx> {
self.node_id_to_type_opt(expr.hir_id)
}
pub fn adjustments(&self) -> LocalTableInContext<Vec<ty::adjustment::Adjustment<'tcx>>> {
LocalTableInContext {
local_id_root: self.local_id_root,
data: &self.adjustments
}
}
pub fn adjustments_mut(&mut self)
-> LocalTableInContextMut<Vec<ty::adjustment::Adjustment<'tcx>>> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.adjustments
}
}
pub fn expr_adjustments(&self, expr: &hir::Expr)
-> &[ty::adjustment::Adjustment<'tcx>] {
self.validate_hir_id(expr.hir_id);
validate_hir_id_for_typeck_tables(self.local_id_root, expr.hir_id);
self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
}
@ -385,48 +528,166 @@ impl<'tcx> TypeckTables<'tcx> {
return false;
}
self.validate_hir_id(expr.hir_id);
match self.type_dependent_defs.get(&expr.hir_id.local_id) {
match self.type_dependent_defs().get(expr.hir_id) {
Some(&Def::Method(_)) => true,
_ => false
}
}
pub fn pat_binding_modes(&self) -> LocalTableInContext<BindingMode> {
LocalTableInContext {
local_id_root: self.local_id_root,
data: &self.pat_binding_modes
}
}
pub fn pat_binding_modes_mut(&mut self)
-> LocalTableInContextMut<BindingMode> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.pat_binding_modes
}
}
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> {
self.upvar_capture_map[&upvar_id]
}
/// Validate that the given HirId (respectively its `local_id` part) can be
/// safely used as a key in the tables of this TypeckTable. For that to be
/// the case, the HirId must have the same `owner` as all the other IDs in
/// this table (signified by the `local_id_root` field). Otherwise the HirId
/// would be in a different frame of reference and using its `local_id`
/// would result in lookup errors, or worse, in silently wrong data being
/// stored/returned.
///
/// Therefore it is advised to call this method anytime before using a given
/// HirId::local_id as a key.
#[inline]
pub fn validate_hir_id(&self, hir_id: hir::HirId) {
#[cfg(debug_assertions)]
{
if self.local_id_root.is_local() {
if hir_id.owner != self.local_id_root.index {
ty::tls::with(|tcx| {
let node_id = tcx.hir
.definitions()
.find_node_for_hir_id(hir_id);
bug!("node {} with HirId::owner {:?} cannot be placed in \
TypeckTables with local_id_root {:?}",
tcx.hir.node_to_string(node_id),
DefId::local(hir_id.owner),
self.local_id_root)
});
}
}
pub fn closure_tys(&self) -> LocalTableInContext<ty::PolyFnSig<'tcx>> {
LocalTableInContext {
local_id_root: self.local_id_root,
data: &self.closure_tys
}
}
pub fn closure_tys_mut(&mut self)
-> LocalTableInContextMut<ty::PolyFnSig<'tcx>> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.closure_tys
}
}
pub fn closure_kinds(&self) -> LocalTableInContext<(ty::ClosureKind,
Option<(Span, ast::Name)>)> {
LocalTableInContext {
local_id_root: self.local_id_root,
data: &self.closure_kinds
}
}
pub fn closure_kinds_mut(&mut self)
-> LocalTableInContextMut<(ty::ClosureKind, Option<(Span, ast::Name)>)> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.closure_kinds
}
}
pub fn liberated_fn_sigs(&self) -> LocalTableInContext<ty::FnSig<'tcx>> {
LocalTableInContext {
local_id_root: self.local_id_root,
data: &self.liberated_fn_sigs
}
}
pub fn liberated_fn_sigs_mut(&mut self) -> LocalTableInContextMut<ty::FnSig<'tcx>> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.liberated_fn_sigs
}
}
pub fn fru_field_types(&self) -> LocalTableInContext<Vec<Ty<'tcx>>> {
LocalTableInContext {
local_id_root: self.local_id_root,
data: &self.fru_field_types
}
}
pub fn fru_field_types_mut(&mut self) -> LocalTableInContextMut<Vec<Ty<'tcx>>> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.fru_field_types
}
}
pub fn cast_kinds(&self) -> LocalTableInContext<ty::cast::CastKind> {
LocalTableInContext {
local_id_root: self.local_id_root,
data: &self.cast_kinds
}
}
pub fn cast_kinds_mut(&mut self) -> LocalTableInContextMut<ty::cast::CastKind> {
LocalTableInContextMut {
local_id_root: self.local_id_root,
data: &mut self.cast_kinds
}
}
}
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for TypeckTables<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
let ty::TypeckTables {
local_id_root,
ref type_dependent_defs,
ref node_types,
ref node_substs,
ref adjustments,
ref pat_binding_modes,
ref upvar_capture_map,
ref closure_tys,
ref closure_kinds,
ref liberated_fn_sigs,
ref fru_field_types,
ref cast_kinds,
ref used_trait_imports,
tainted_by_errors,
ref free_region_map,
} = *self;
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
ich::hash_stable_itemlocalmap(hcx, hasher, type_dependent_defs);
ich::hash_stable_itemlocalmap(hcx, hasher, node_types);
ich::hash_stable_itemlocalmap(hcx, hasher, node_substs);
ich::hash_stable_itemlocalmap(hcx, hasher, adjustments);
ich::hash_stable_itemlocalmap(hcx, hasher, pat_binding_modes);
ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
let ty::UpvarId {
var_id,
closure_expr_id
} = *up_var_id;
let var_def_id = DefId {
krate: local_id_root.krate,
index: var_id,
};
let closure_def_id = DefId {
krate: local_id_root.krate,
index: closure_expr_id,
};
(hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
});
ich::hash_stable_itemlocalmap(hcx, hasher, closure_tys);
ich::hash_stable_itemlocalmap(hcx, hasher, closure_kinds);
ich::hash_stable_itemlocalmap(hcx, hasher, liberated_fn_sigs);
ich::hash_stable_itemlocalmap(hcx, hasher, fru_field_types);
ich::hash_stable_itemlocalmap(hcx, hasher, cast_kinds);
ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| {
hcx.def_path_hash(*def_id)
});
tainted_by_errors.hash_stable(hcx, hasher);
free_region_map.hash_stable(hcx, hasher);
})
}
}
impl<'tcx> CommonTypes<'tcx> {

View File

@ -600,9 +600,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
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(&hir_id.local_id)
self.tables.closure_kinds().get(hir_id)
{
err.span_note(span, &format!(
"closure cannot be invoked more than once because \
@ -904,10 +903,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
match pat.node {
hir::PatKind::Binding(..) => {
self.tables.validate_hir_id(pat.hir_id);
*self.tables
.pat_binding_modes
.get(&pat.hir_id.local_id)
.pat_binding_modes()
.get(pat.hir_id)
.expect("missing binding mode")
}
_ => bug!("local is not a binding: {:?}", pat)

View File

@ -269,10 +269,9 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
fn check_for_bindings_named_the_same_as_variants(cx: &MatchVisitor, pat: &Pat) {
pat.walk(|p| {
if let PatKind::Binding(_, _, name, None) = p.node {
cx.tables.validate_hir_id(p.hir_id);
let bm = *cx.tables
.pat_binding_modes
.get(&p.hir_id.local_id)
.pat_binding_modes()
.get(p.hir_id)
.expect("missing binding mode");
if bm != ty::BindByValue(hir::MutImmutable) {
@ -464,10 +463,9 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
for pat in pats {
pat.each_binding(|_, id, span, _path| {
let hir_id = cx.tcx.hir.node_to_hir_id(id);
cx.tables.validate_hir_id(hir_id);
let bm = *cx.tables
.pat_binding_modes
.get(&hir_id.local_id)
.pat_binding_modes()
.get(hir_id)
.expect("missing binding mode");
if let ty::BindByReference(..) = bm {
by_ref_span = Some(span);
@ -501,10 +499,9 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
for pat in pats {
pat.walk(|p| {
if let PatKind::Binding(_, _, _, ref sub) = p.node {
cx.tables.validate_hir_id(p.hir_id);
let bm = *cx.tables
.pat_binding_modes
.get(&p.hir_id.local_id)
.pat_binding_modes()
.get(p.hir_id)
.expect("missing binding mode");
match bm {
ty::BindByValue(..) => {

View File

@ -381,8 +381,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
ty::TyRef(r, _) => Some(r),
_ => None,
};
let bm = *self.tables.pat_binding_modes.get(&pat.hir_id.local_id)
.expect("missing binding mode");
let bm = *self.tables.pat_binding_modes().get(pat.hir_id)
.expect("missing binding mode");
let (mutability, mode) = match bm {
ty::BindByValue(hir::MutMutable) =>
(Mutability::Mut, BindingMode::ByValue),

View File

@ -935,7 +935,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
// Check for method calls and overloaded operators.
if cx.tables.is_method_call(expr) {
let hir_id = cx.tcx.hir.definitions().node_to_hir_id(id);
let def_id = cx.tables.type_dependent_defs[&hir_id.local_id].def_id();
let def_id = cx.tables.type_dependent_defs()[hir_id].def_id();
let substs = cx.tables.node_substs(hir_id);
if method_call_refers_to_method(cx, method, def_id, substs, id) {
return true;

View File

@ -46,8 +46,7 @@ impl UnusedMut {
for p in pats {
p.each_binding(|_, id, span, path1| {
let hir_id = cx.tcx.hir.node_to_hir_id(id);
cx.tables.validate_hir_id(hir_id);
let bm = match cx.tables.pat_binding_modes.get(&hir_id.local_id) {
let bm = match cx.tables.pat_binding_modes().get(hir_id) {
Some(&bm) => bm,
None => span_bug!(span, "missing binding mode"),
};

View File

@ -91,8 +91,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
// fetch the fully liberated fn signature (that is, all bound
// types/lifetimes replaced)
let fn_hir_id = tcx.hir.node_to_hir_id(id);
cx.tables().validate_hir_id(fn_hir_id);
let fn_sig = cx.tables().liberated_fn_sigs[&fn_hir_id.local_id].clone();
let fn_sig = cx.tables().liberated_fn_sigs()[fn_hir_id].clone();
let ty = tcx.type_of(tcx.hir.local_def_id(id));
let mut abi = fn_sig.abi;

View File

@ -387,11 +387,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
substs: substs,
fields: field_refs,
base: base.as_ref().map(|base| {
cx.tables().validate_hir_id(expr.hir_id);
FruInfo {
base: base.to_ref(),
field_types: cx.tables()
.fru_field_types[&expr.hir_id.local_id]
.fru_field_types()[expr.hir_id]
.clone(),
}
}),
@ -551,10 +550,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
hir::ExprCast(ref source, _) => {
// Check to see if this cast is a "coercion cast", where the cast is actually done
// using a coercion (or is a no-op).
cx.tables().validate_hir_id(source.hir_id);
if let Some(&TyCastKind::CoercionCast) = cx.tables()
.cast_kinds
.get(&source.hir_id.local_id) {
.cast_kinds()
.get(source.hir_id) {
// Convert the lexpr to a vexpr.
ExprKind::Use { source: source.to_ref() }
} else {
@ -586,8 +584,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
-> Expr<'tcx> {
let temp_lifetime = cx.region_maps.temporary_scope(expr.id);
let (def_id, substs) = custom_callee.unwrap_or_else(|| {
cx.tables().validate_hir_id(expr.hir_id);
(cx.tables().type_dependent_defs[&expr.hir_id.local_id].def_id(),
(cx.tables().type_dependent_defs()[expr.hir_id].def_id(),
cx.tables().node_substs(expr.hir_id))
});
Expr {

View File

@ -320,8 +320,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
}
hir::ExprCast(ref from, _) => {
debug!("Checking const cast(id={})", from.id);
v.tables.validate_hir_id(from.hir_id);
match v.tables.cast_kinds.get(&from.hir_id.local_id) {
match v.tables.cast_kinds().get(from.hir_id) {
None => span_bug!(e.span, "no kind for cast"),
Some(&CastKind::PtrAddrCast) | Some(&CastKind::FnPtrAddrCast) => {
v.promotable = false;
@ -388,8 +387,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
}
}
hir::ExprMethodCall(..) => {
v.tables.validate_hir_id(e.hir_id);
let def_id = v.tables.type_dependent_defs[&e.hir_id.local_id].def_id();
let def_id = v.tables.type_dependent_defs()[e.hir_id].def_id();
match v.tcx.associated_item(def_id).container {
ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty),
ty::TraitContainer(_) => v.promotable = false

View File

@ -649,7 +649,7 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
if self.tables.node_substs(id).visit_with(self) {
return true;
}
if let Some(adjustments) = self.tables.adjustments.get(&id.local_id) {
if let Some(adjustments) = self.tables.adjustments().get(id) {
for adjustment in adjustments {
if adjustment.target.visit_with(self) {
return true;
@ -748,8 +748,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
}
hir::ExprMethodCall(_, span, _) => {
// Method calls have to be checked specially.
self.tables.validate_hir_id(expr.hir_id);
let def_id = self.tables.type_dependent_defs[&expr.hir_id.local_id].def_id();
let def_id = self.tables.type_dependent_defs()[expr.hir_id].def_id();
self.span = span;
if self.tcx.type_of(def_id).visit_with(self) {
return;
@ -766,8 +765,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
// we have to check it additionally.
if let hir::QPath::TypeRelative(..) = *qpath {
let hir_id = self.tcx.hir.node_to_hir_id(id);
self.tables.validate_hir_id(hir_id);
if let Some(def) = self.tables.type_dependent_defs.get(&hir_id.local_id).cloned() {
if let Some(def) = self.tables.type_dependent_defs().get(hir_id).cloned() {
if let Some(assoc_item) = self.tcx.opt_associated_item(def.def_id()) {
if let ty::ImplContainer(impl_def_id) = assoc_item.container {
if self.tcx.type_of(impl_def_id).visit_with(self) {

View File

@ -550,8 +550,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}
}
ast::ExprKind::MethodCall(..) => {
let local_id = self.tcx.hir.definitions().node_to_hir_id(expr.id).local_id;
let method_id = self.tables.type_dependent_defs[&local_id].def_id();
let expr_hir_id = self.tcx.hir.definitions().node_to_hir_id(expr.id);
let method_id = self.tables.type_dependent_defs()[expr_hir_id].def_id();
let (def_id, decl_id) = match self.tcx.associated_item(method_id).container {
ty::ImplContainer(_) => (Some(method_id), None),
ty::TraitContainer(_) => (None, Some(method_id)),

View File

@ -118,11 +118,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// identical to what could be scraped from the HIR, but this will change with
// default binding modes (#42640).
let bm = ty::BindingMode::convert(ba);
{
let mut inh_tables = self.inh.tables.borrow_mut();
inh_tables.validate_hir_id(pat.hir_id);
inh_tables.pat_binding_modes.insert(pat.hir_id.local_id, bm);
}
self.inh
.tables
.borrow_mut()
.pat_binding_modes_mut()
.insert(pat.hir_id, bm);
let typ = self.local_ty(pat.span, pat.id);
match bm {
ty::BindByReference(mutbl) => {

View File

@ -330,16 +330,13 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
} else if self.try_coercion_cast(fcx) {
self.trivial_cast_lint(fcx);
debug!(" -> CoercionCast");
let mut tables = fcx.tables.borrow_mut();
tables.validate_hir_id(self.expr.hir_id);
tables.cast_kinds.insert(self.expr.hir_id.local_id, CastKind::CoercionCast);
fcx.tables.borrow_mut().cast_kinds_mut().insert(self.expr.hir_id,
CastKind::CoercionCast);
} else {
match self.do_check(fcx) {
Ok(k) => {
debug!(" -> {:?}", k);
let mut tables = fcx.tables.borrow_mut();
tables.validate_hir_id(self.expr.hir_id);
tables.cast_kinds.insert(self.expr.hir_id.local_id, k);
fcx.tables.borrow_mut().cast_kinds_mut().insert(self.expr.hir_id, k);
}
Err(e) => self.report_cast_error(fcx, e),
};

View File

@ -104,11 +104,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
{
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(expr.hir_id);
tables.closure_tys.insert(expr.hir_id.local_id, sig);
tables.closure_tys_mut().insert(expr.hir_id, sig);
match opt_kind {
Some(kind) => {
tables.closure_kinds.insert(expr.hir_id.local_id, (kind, None));
tables.closure_kinds_mut().insert(expr.hir_id, (kind, None));
}
None => {}
}

View File

@ -844,7 +844,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// First try to coerce the new expression to the type of the previous ones,
// but only if the new expression has no coercion already applied to it.
let mut first_error = None;
if !self.tables.borrow().adjustments.contains_key(&new.hir_id.local_id) {
if !self.tables.borrow().adjustments().contains_key(new.hir_id) {
let result = self.commit_if_ok(|_| coerce.coerce(new_ty, prev_ty));
match result {
Ok(ok) => {

View File

@ -451,8 +451,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
// tables borrowed during (`deref_mut`) method resolution.
let previous_adjustments = self.tables
.borrow_mut()
.adjustments
.remove(&expr.hir_id.local_id);
.adjustments_mut()
.remove(expr.hir_id);
if let Some(mut adjustments) = previous_adjustments {
let pref = LvaluePreference::PreferMutLvalue;
for adjustment in &mut adjustments {
@ -469,7 +469,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
}
source = adjustment.target;
}
self.tables.borrow_mut().adjustments.insert(expr.hir_id.local_id, adjustments);
self.tables.borrow_mut().adjustments_mut().insert(expr.hir_id, adjustments);
}
match expr.node {
@ -529,8 +529,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
let base_expr_ty = self.node_ty(base_expr.hir_id);
if let Some(adjustments) = self.tables
.borrow_mut()
.adjustments
.get_mut(&base_expr.hir_id.local_id) {
.adjustments_mut()
.get_mut(base_expr.hir_id) {
let mut source = base_expr_ty;
for adjustment in &mut adjustments[..] {
if let Adjust::Borrow(AutoBorrow::Ref(..)) = adjustment.kind {

View File

@ -829,9 +829,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
};
let closure_kind = {
let tables = self.tables.borrow();
tables.validate_hir_id(closure_id);
match tables.closure_kinds.get(&closure_id.local_id) {
match self.tables.borrow().closure_kinds().get(closure_id) {
Some(&(k, _)) => k,
None => {
return Err(MethodError::ClosureAmbiguity(trait_def_id));

View File

@ -744,7 +744,7 @@ fn closure_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-> ty::ClosureKind {
let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
let hir_id = tcx.hir.node_to_hir_id(node_id);
tcx.typeck_tables_of(def_id).closure_kinds[&hir_id.local_id].0
tcx.typeck_tables_of(def_id).closure_kinds()[hir_id].0
}
fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
@ -1028,12 +1028,8 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
fcx.write_ty(arg.hir_id, arg_ty);
}
{
let mut inh_tables = inherited.tables.borrow_mut();
let fn_hir_id = fcx.tcx.hir.node_to_hir_id(fn_id);
inh_tables.validate_hir_id(fn_hir_id);
inh_tables.liberated_fn_sigs.insert(fn_hir_id.local_id, fn_sig);
}
let fn_hir_id = fcx.tcx.hir.node_to_hir_id(fn_id);
inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_hir_id, fn_sig);
fcx.check_return_expr(&body.value);
@ -1816,11 +1812,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
debug!("write_ty({:?}, {:?}) in fcx {}",
id, self.resolve_type_vars_if_possible(&ty), self.tag());
{
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(id);
tables.node_types.insert(id.local_id, ty);
}
self.tables.borrow_mut().node_types_mut().insert(id, ty);
if ty.references_error() {
self.has_errors.set(true);
@ -1833,11 +1825,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn write_method_call(&self,
hir_id: hir::HirId,
method: MethodCallee<'tcx>) {
{
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(hir_id);
tables.type_dependent_defs.insert(hir_id.local_id, Def::Method(method.def_id));
}
self.tables
.borrow_mut()
.type_dependent_defs_mut()
.insert(hir_id, Def::Method(method.def_id));
self.write_substs(hir_id, method.substs);
}
@ -1848,9 +1839,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
substs,
self.tag());
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(node_id);
tables.node_substs.insert(node_id.local_id, substs);
self.tables.borrow_mut().node_substs_mut().insert(node_id, substs);
}
}
@ -1861,9 +1850,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
return;
}
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(expr.hir_id);
match tables.adjustments.entry(expr.hir_id.local_id) {
match self.tables.borrow_mut().adjustments_mut().entry(expr.hir_id) {
Entry::Vacant(entry) => { entry.insert(adj); },
Entry::Occupied(mut entry) => {
debug!(" - composing on top of {:?}", entry.get());
@ -2017,9 +2004,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
let tables = self.tables.borrow();
tables.validate_hir_id(id);
match tables.node_types.get(&id.local_id) {
match self.tables.borrow().node_types().get(id) {
Some(&t) => t,
None if self.err_count_since_creation() != 0 => self.tcx.types.err,
None => {
@ -2682,7 +2667,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// While we don't allow *arbitrary* coercions here, we *do* allow
// coercions from ! to `expected`.
if ty.is_never() {
assert!(!self.tables.borrow().adjustments.contains_key(&expr.hir_id.local_id),
assert!(!self.tables.borrow().adjustments().contains_key(expr.hir_id),
"expression with never type wound up being adjusted");
let adj_ty = self.next_diverging_ty_var(
TypeVariableOrigin::AdjustmentType(expr.span));
@ -3408,9 +3393,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.normalize_associated_types_in(expr.span, &f.ty(self.tcx, substs))
}).collect();
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(expr.hir_id);
tables.fru_field_types.insert(expr.hir_id.local_id, fru_field_types);
self.tables
.borrow_mut()
.fru_field_types_mut()
.insert(expr.hir_id, fru_field_types);
}
_ => {
span_err!(self.tcx.sess, base_expr.span, E0436,
@ -4043,9 +4029,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Write back the new resolution.
let hir_id = self.tcx.hir.node_to_hir_id(node_id);
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(hir_id);
tables.type_dependent_defs.insert(hir_id.local_id, def);
self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
(def, ty)
}
@ -4087,9 +4071,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Write back the new resolution.
let hir_id = self.tcx.hir.node_to_hir_id(node_id);
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(hir_id);
tables.type_dependent_defs.insert(hir_id.local_id, def);
self.tables.borrow_mut().type_dependent_defs_mut().insert(hir_id, def);
(def, Some(ty), slice::ref_slice(&**item_segment))
}

View File

@ -210,10 +210,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// some cases applied on the RHS, on top of which we need
// to autoref, which is not allowed by apply_adjustments.
// self.apply_adjustments(rhs_expr, vec![autoref]);
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(rhs_expr.hir_id);
tables.adjustments.entry(rhs_expr.hir_id.local_id)
.or_insert(vec![]).push(autoref);
self.tables
.borrow_mut()
.adjustments_mut()
.entry(rhs_expr.hir_id)
.or_insert(vec![])
.push(autoref);
}
}
self.write_method_call(expr.hir_id, method);

View File

@ -309,10 +309,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
let old_call_site_scope = self.set_call_site_scope(Some(call_site));
let fn_sig = {
let tables = self.tables.borrow();
let fn_hir_id = self.tcx.hir.node_to_hir_id(id);
tables.validate_hir_id(fn_hir_id);
match tables.liberated_fn_sigs.get(&fn_hir_id.local_id) {
match self.tables.borrow().liberated_fn_sigs().get(fn_hir_id) {
Some(f) => f.clone(),
None => {
bug!("No fn-sig entry for id={}", id);
@ -1121,14 +1119,12 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
// report errors later on in the writeback phase.
let ty0 = self.resolve_node_type(hir_id);
let ty = {
let tables = self.tables.borrow();
tables.validate_hir_id(hir_id);
tables.adjustments
.get(&hir_id.local_id)
.and_then(|adj| adj.last())
.map_or(ty0, |adj| adj.target)
};
let ty = self.tables
.borrow()
.adjustments()
.get(hir_id)
.and_then(|adj| adj.last())
.map_or(ty0, |adj| adj.target);
let ty = self.resolve_type(ty);
debug!("constrain_regions_in_type_of_node(\
ty={}, ty0={}, id={:?}, minimum_lifetime={:?})",
@ -1207,9 +1203,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
match sub_pat.node {
// `ref x` pattern
PatKind::Binding(..) => {
mc.tables.validate_hir_id(sub_pat.hir_id);
let bm = *mc.tables.pat_binding_modes.get(&sub_pat.hir_id.local_id)
.expect("missing binding mode");
let bm = *mc.tables.pat_binding_modes().get(sub_pat.hir_id)
.expect("missing binding mode");
if let ty::BindByReference(mutbl) = bm {
self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id,
mutbl, sub_cmt);

View File

@ -103,8 +103,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let infer_kind = match self.tables
.borrow_mut()
.closure_kinds
.entry(closure_hir_id.local_id) {
.closure_kinds_mut()
.entry(closure_hir_id) {
Entry::Occupied(_) => false,
Entry::Vacant(entry) => {
debug!("check_closure: adding closure {:?} as Fn", closure_node_id);
@ -162,8 +162,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
.remove(&closure_def_id.index) {
self.tables
.borrow_mut()
.closure_kinds
.insert(closure_hir_id.local_id, kind);
.closure_kinds_mut()
.insert(closure_hir_id, kind);
}
}
self.tables.borrow_mut().upvar_capture_map.extend(
@ -482,9 +482,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
let closure_kind = self.adjust_closure_kinds.get(&closure_id).cloned()
.or_else(|| {
let closure_id = self.fcx.tcx.hir.def_index_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()
self.fcx.tables.borrow().closure_kinds().get(closure_id).cloned()
});
if let Some((existing_kind, _)) = closure_kind {

View File

@ -93,8 +93,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'gcx>) {
debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
assert!(!ty.needs_infer());
self.tables.validate_hir_id(hir_id);
self.tables.node_types.insert(hir_id.local_id, ty);
self.tables.node_types_mut().insert(hir_id, ty);
}
// Hacky hack: During type-checking, we treat *all* operators
@ -110,9 +109,8 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
if inner_ty.is_scalar() {
let mut tables = self.fcx.tables.borrow_mut();
tables.validate_hir_id(e.hir_id);
tables.type_dependent_defs.remove(&e.hir_id.local_id);
tables.node_substs.remove(&e.hir_id.local_id);
tables.type_dependent_defs_mut().remove(e.hir_id);
tables.node_substs_mut().remove(e.hir_id);
}
}
hir::ExprBinary(ref op, ref lhs, ref rhs) |
@ -125,19 +123,19 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
let mut tables = self.fcx.tables.borrow_mut();
tables.validate_hir_id(e.hir_id);
tables.type_dependent_defs.remove(&e.hir_id.local_id);
tables.node_substs.remove(&e.hir_id.local_id);
tables.type_dependent_defs_mut().remove(e.hir_id);
tables.node_substs_mut().remove(e.hir_id);
match e.node {
hir::ExprBinary(..) => {
if !op.node.is_by_value() {
tables.adjustments.get_mut(&lhs.hir_id.local_id).map(|a| a.pop());
tables.adjustments.get_mut(&rhs.hir_id.local_id).map(|a| a.pop());
let mut adjustments = tables.adjustments_mut();
adjustments.get_mut(lhs.hir_id).map(|a| a.pop());
adjustments.get_mut(rhs.hir_id).map(|a| a.pop());
}
},
hir::ExprAssignOp(..) => {
tables.adjustments.get_mut(&lhs.hir_id.local_id).map(|a| a.pop());
tables.adjustments_mut().get_mut(lhs.hir_id).map(|a| a.pop());
},
_ => {},
}
@ -186,14 +184,13 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
fn visit_pat(&mut self, p: &'gcx hir::Pat) {
match p.node {
hir::PatKind::Binding(..) => {
let bm = {
let fcx_tables = self.fcx.tables.borrow();
fcx_tables.validate_hir_id(p.hir_id);
*fcx_tables.pat_binding_modes.get(&p.hir_id.local_id)
.expect("missing binding mode")
};
self.tables.validate_hir_id(p.hir_id);
self.tables.pat_binding_modes.insert(p.hir_id.local_id, bm);
let bm = *self.fcx
.tables
.borrow()
.pat_binding_modes()
.get(p.hir_id)
.expect("missing binding mode");
self.tables.pat_binding_modes_mut().insert(p.hir_id, bm);
}
_ => {}
};
@ -233,23 +230,36 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
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() {
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);
self.tables.closure_tys_mut().insert(hir_id, closure_ty);
}
for (&id, &closure_kind) in fcx_tables.closure_kinds.iter() {
self.tables.closure_kinds.insert(id, closure_kind);
for (&id, &closure_kind) in fcx_tables.closure_kinds().iter() {
let hir_id = hir::HirId {
owner: fcx_tables.local_id_root.index,
local_id: id,
};
self.tables.closure_kinds_mut().insert(hir_id, closure_kind);
}
}
fn visit_cast_types(&mut self) {
self.tables.cast_kinds.extend(
self.fcx.tables.borrow().cast_kinds.iter().map(|(&key, &value)| (key, value)));
let fcx_tables = self.fcx.tables.borrow();
let fcx_cast_kinds = fcx_tables.cast_kinds();
let mut self_cast_kinds = self.tables.cast_kinds_mut();
for (&local_id, &cast_kind) in fcx_cast_kinds.iter() {
let hir_id = hir::HirId {
owner: fcx_tables.local_id_root.index,
local_id,
};
self_cast_kinds.insert(hir_id, cast_kind);
}
}
fn visit_free_region_map(&mut self) {
@ -293,20 +303,18 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
});
let hir_id = self.tcx().hir.node_to_hir_id(node_id);
self.tables.validate_hir_id(hir_id);
self.tables.node_types.insert(hir_id.local_id, outside_ty);
self.tables.node_types_mut().insert(hir_id, outside_ty);
}
}
fn visit_node_id(&mut self, span: Span, hir_id: hir::HirId) {
{
let mut fcx_tables = self.fcx.tables.borrow_mut();
fcx_tables.validate_hir_id(hir_id);
// Export associated path extensions and method resultions.
if let Some(def) = fcx_tables.type_dependent_defs.remove(&hir_id.local_id) {
self.tables.validate_hir_id(hir_id);
self.tables.type_dependent_defs.insert(hir_id.local_id, def);
}
// Export associated path extensions and method resultions.
if let Some(def) = self.fcx
.tables
.borrow_mut()
.type_dependent_defs_mut()
.remove(hir_id) {
self.tables.type_dependent_defs_mut().insert(hir_id, def);
}
// Resolve any borrowings for the node with id `node_id`
@ -319,20 +327,20 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
debug!("Node {:?} has type {:?}", hir_id, n_ty);
// Resolve any substitutions
if let Some(&substs) = self.fcx.tables.borrow().node_substs.get(&hir_id.local_id) {
if let Some(substs) = self.fcx.tables.borrow().node_substs_opt(hir_id) {
let substs = self.resolve(&substs, &span);
debug!("write_substs_to_tcx({:?}, {:?})", hir_id, substs);
assert!(!substs.needs_infer());
self.tables.node_substs.insert(hir_id.local_id, substs);
self.tables.node_substs_mut().insert(hir_id, substs);
}
}
fn visit_adjustments(&mut self, span: Span, hir_id: hir::HirId) {
let adjustment = {
let mut fcx_tables = self.fcx.tables.borrow_mut();
fcx_tables.validate_hir_id(hir_id);
fcx_tables.adjustments.remove(&hir_id.local_id)
};
let adjustment = self.fcx
.tables
.borrow_mut()
.adjustments_mut()
.remove(hir_id);
match adjustment {
None => {
debug!("No adjustments for node {:?}", hir_id);
@ -341,8 +349,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
Some(adjustment) => {
let resolved_adjustment = self.resolve(&adjustment, &span);
debug!("Adjustments for node {:?}: {:?}", hir_id, resolved_adjustment);
self.tables.validate_hir_id(hir_id);
self.tables.adjustments.insert(hir_id.local_id, resolved_adjustment);
self.tables.adjustments_mut().insert(hir_id, resolved_adjustment);
}
}
}
@ -351,13 +358,13 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
let fcx_tables = self.fcx.tables.borrow();
debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
for (&local_id, fn_sig) in fcx_tables.liberated_fn_sigs.iter() {
for (&local_id, fn_sig) in fcx_tables.liberated_fn_sigs().iter() {
let hir_id = hir::HirId {
owner: fcx_tables.local_id_root.index,
local_id,
};
let fn_sig = self.resolve(fn_sig, &hir_id);
self.tables.liberated_fn_sigs.insert(local_id, fn_sig.clone());
self.tables.liberated_fn_sigs_mut().insert(hir_id, fn_sig.clone());
}
}
@ -365,13 +372,13 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
let fcx_tables = self.fcx.tables.borrow();
debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
for (&local_id, ftys) in fcx_tables.fru_field_types.iter() {
for (&local_id, ftys) in fcx_tables.fru_field_types().iter() {
let hir_id = hir::HirId {
owner: fcx_tables.local_id_root.index,
local_id,
};
let ftys = self.resolve(ftys, &hir_id);
self.tables.fru_field_types.insert(local_id, ftys);
self.tables.fru_field_types_mut().insert(hir_id, ftys);
}
}

View File

@ -1240,9 +1240,7 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
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]
tcx.typeck_tables_of(def_id).closure_tys()[hir_id]
}
x => {