Encapsulate sub-table access in TypeckTables and validate keys on each access.
This commit is contained in:
parent
bdfd78db8a
commit
1f54df1101
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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")
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 \
|
||||
|
@ -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> {
|
||||
|
@ -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)
|
||||
|
@ -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(..) => {
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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"),
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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)),
|
||||
|
@ -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) => {
|
||||
|
@ -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),
|
||||
};
|
||||
|
@ -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 => {}
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 => {
|
||||
|
Loading…
Reference in New Issue
Block a user