pub fn is_local(&self) -> bool {
self.krate == LOCAL_CRATE
}
+
+ pub fn invalid() -> DefId {
+ DefId {
+ krate: INVALID_CRATE,
+ index: CRATE_DEF_INDEX,
+ }
+ }
}
Optional
}
+struct LoweredNodeId {
+ node_id: NodeId,
+ hir_id: hir::HirId,
+}
+
impl<'a> LoweringContext<'a> {
fn lower_crate(mut self, c: &Crate) -> hir::Crate {
/// Full-crate AST visitor that inserts into a fresh
fn lower_node_id_generic<F>(&mut self,
ast_node_id: NodeId,
alloc_hir_id: F)
- -> NodeId
+ -> LoweredNodeId
where F: FnOnce(&mut Self) -> hir::HirId
{
if ast_node_id == DUMMY_NODE_ID {
- return ast_node_id;
+ return LoweredNodeId {
+ node_id: DUMMY_NODE_ID,
+ hir_id: hir::DUMMY_HIR_ID,
+ }
}
let min_size = ast_node_id.as_usize() + 1;
self.node_id_to_hir_id.resize(min_size, hir::DUMMY_HIR_ID);
}
- if self.node_id_to_hir_id[ast_node_id] == hir::DUMMY_HIR_ID {
+ let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
+
+ if existing_hir_id == hir::DUMMY_HIR_ID {
// Generate a new HirId
- self.node_id_to_hir_id[ast_node_id] = alloc_hir_id(self);
+ let hir_id = alloc_hir_id(self);
+ self.node_id_to_hir_id[ast_node_id] = hir_id;
+ LoweredNodeId {
+ node_id: ast_node_id,
+ hir_id,
+ }
+ } else {
+ LoweredNodeId {
+ node_id: ast_node_id,
+ hir_id: existing_hir_id,
+ }
}
-
- ast_node_id
}
fn with_hir_id_owner<F>(&mut self, owner: NodeId, f: F)
/// actually used in the HIR, as that would trigger an assertion in the
/// HirIdValidator later on, which makes sure that all NodeIds got mapped
/// properly. Calling the method twice with the same NodeId is fine though.
- fn lower_node_id(&mut self, ast_node_id: NodeId) -> NodeId {
+ fn lower_node_id(&mut self, ast_node_id: NodeId) -> LoweredNodeId {
self.lower_node_id_generic(ast_node_id, |this| {
let &mut (def_index, ref mut local_id_counter) = this.current_hir_id_owner
.last_mut()
fn lower_node_id_with_owner(&mut self,
ast_node_id: NodeId,
owner: NodeId)
- -> NodeId {
+ -> LoweredNodeId {
self.lower_node_id_generic(ast_node_id, |this| {
let local_id_counter = this.item_local_id_counters
.get_mut(&owner)
id
}
- fn next_id(&mut self) -> NodeId {
+ fn next_id(&mut self) -> LoweredNodeId {
self.lower_node_id(self.sess.next_node_id())
}
match destination {
Some((id, label_ident)) => {
let target = if let Def::Label(loop_id) = self.expect_full_def(id) {
- hir::LoopIdResult::Ok(self.lower_node_id(loop_id))
+ hir::LoopIdResult::Ok(self.lower_node_id(loop_id).node_id)
} else {
hir::LoopIdResult::Err(hir::LoopIdError::UnresolvedLabel)
};
hir::Destination {
ident: None,
target_id: hir::ScopeTarget::Loop(
- loop_id.map(|id| Ok(self.lower_node_id(id)))
+ loop_id.map(|id| Ok(self.lower_node_id(id).node_id))
.unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
.into())
}
fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
hir::TypeBinding {
- id: self.lower_node_id(b.id),
+ id: self.lower_node_id(b.id).node_id,
name: self.lower_ident(b.ident),
ty: self.lower_ty(&b.ty),
span: b.span,
return self.lower_ty(ty);
}
TyKind::Path(ref qself, ref path) => {
- let id = self.lower_node_id(t.id);
+ let id = self.lower_node_id(t.id).node_id;
let qpath = self.lower_qpath(t.id, qself, path, ParamMode::Explicit);
return self.ty_path(id, t.span, qpath);
}
};
P(hir::Ty {
- id: self.lower_node_id(t.id),
+ id: self.lower_node_id(t.id).node_id,
node: kind,
span: t.span,
})
// Otherwise, the base path is an implicit `Self` type path,
// e.g. `Vec` in `Vec::new` or `<I as Iterator>::Item` in
// `<I as Iterator>::Item::default`.
- let new_id = self.next_id();
+ let new_id = self.next_id().node_id;
self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path))
};
}
// Wrap the associated extension in another type node.
- let new_id = self.next_id();
+ let new_id = self.next_id().node_id;
ty = self.ty_path(new_id, p.span, qpath);
}
fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
P(hir::Local {
- id: self.lower_node_id(l.id),
+ id: self.lower_node_id(l.id).node_id,
ty: l.ty.as_ref().map(|t| self.lower_ty(t)),
pat: self.lower_pat(&l.pat),
init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
}
fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
+ let LoweredNodeId { node_id, hir_id } = self.lower_node_id(arg.id);
hir::Arg {
- id: self.lower_node_id(arg.id),
+ id: node_id,
+ hir_id,
pat: self.lower_pat(&arg.pat),
}
}
}
hir::TyParam {
- id: self.lower_node_id(tp.id),
+ id: self.lower_node_id(tp.id).node_id,
name,
bounds,
default: tp.default.as_ref().map(|x| self.lower_ty(x)),
fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
hir::Lifetime {
- id: self.lower_node_id(l.id),
+ id: self.lower_node_id(l.id).node_id,
name: self.lower_ident(l.ident),
span: l.span,
}
fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
hir::WhereClause {
- id: self.lower_node_id(wc.id),
+ id: self.lower_node_id(wc.id).node_id,
predicates: wc.predicates
.iter()
.map(|predicate| self.lower_where_predicate(predicate))
ref rhs_ty,
span}) => {
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
- id: self.lower_node_id(id),
+ id: self.lower_node_id(id).node_id,
lhs_ty: self.lower_ty(lhs_ty),
rhs_ty: self.lower_ty(rhs_ty),
span,
.enumerate()
.map(|f| self.lower_struct_field(f))
.collect(),
- self.lower_node_id(id))
+ self.lower_node_id(id).node_id)
}
VariantData::Tuple(ref fields, id) => {
hir::VariantData::Tuple(fields.iter()
.enumerate()
.map(|f| self.lower_struct_field(f))
.collect(),
- self.lower_node_id(id))
+ self.lower_node_id(id).node_id)
}
- VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id)),
+ VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id).node_id),
}
}
};
hir::TraitRef {
path,
- ref_id: self.lower_node_id(p.ref_id),
+ ref_id: self.lower_node_id(p.ref_id).node_id,
}
}
fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
hir::StructField {
span: f.span,
- id: self.lower_node_id(f.id),
+ id: self.lower_node_id(f.id).node_id,
name: self.lower_ident(match f.ident {
Some(ident) => ident,
// FIXME(jseyfried) positional field hygiene
}
}
+ let LoweredNodeId { node_id, hir_id } = self.lower_node_id(b.id);
+
P(hir::Block {
- id: self.lower_node_id(b.id),
+ id: node_id,
+ hir_id,
stmts: stmts.into(),
expr,
rules: self.lower_block_check_mode(&b.rules),
hir::Visibility::Restricted {
path: path.clone(),
// We are allocating a new NodeId here
- id: this.next_id(),
+ id: this.next_id().node_id,
}
}
};
fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
self.with_parent_def(i.id, |this| {
hir::TraitItem {
- id: this.lower_node_id(i.id),
+ id: this.lower_node_id(i.id).node_id,
name: this.lower_ident(i.ident),
attrs: this.lower_attrs(&i.attrs),
node: match i.node {
fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
self.with_parent_def(i.id, |this| {
hir::ImplItem {
- id: this.lower_node_id(i.id),
+ id: this.lower_node_id(i.id).node_id,
name: this.lower_ident(i.ident),
attrs: this.lower_attrs(&i.attrs),
vis: this.lower_visibility(&i.vis, None),
});
Some(hir::Item {
- id: self.lower_node_id(i.id),
+ id: self.lower_node_id(i.id).node_id,
name,
attrs,
node,
fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
self.with_parent_def(i.id, |this| {
hir::ForeignItem {
- id: this.lower_node_id(i.id),
+ id: this.lower_node_id(i.id).node_id,
name: i.ident.name,
attrs: this.lower_attrs(&i.attrs),
node: match i.node {
}
fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
+ let LoweredNodeId { node_id, hir_id } = self.lower_node_id(p.id);
+
P(hir::Pat {
- id: self.lower_node_id(p.id),
+ id: node_id,
+ hir_id,
node: match p.node {
PatKind::Wild => hir::PatKind::Wild,
PatKind::Ident(ref binding_mode, pth1, ref sub) => {
let call_move_val_init =
hir::StmtSemi(
make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
- self.next_id());
+ self.next_id().node_id);
let call_move_val_init = respan(e.span, call_move_val_init);
let place = self.expr_ident(e.span, place_ident, place_binding);
// wrap the if-let expr in a block
let span = els.span;
let els = P(self.lower_expr(els));
- let id = self.next_id();
+ let LoweredNodeId {
+ node_id,
+ hir_id,
+ } = self.next_id();
let blk = P(hir::Block {
stmts: hir_vec![],
expr: Some(els),
- id,
+ id: node_id,
+ hir_id,
rules: hir::DefaultBlock,
span,
targeted_by_break: false,
let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
let struct_path = hir::QPath::Resolved(None, P(struct_path));
+ let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
+
return hir::Expr {
- id: self.lower_node_id(e.id),
+ id: node_id,
+ hir_id,
node: if is_unit {
hir::ExprPath(struct_path)
} else {
hir::MatchSource::ForLoopDesugar),
ThinVec::new()))
};
- let match_stmt = respan(e.span, hir::StmtExpr(match_expr, self.next_id()));
+ let match_stmt = respan(e.span, hir::StmtExpr(match_expr, self.next_id().node_id));
let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
let body_block = self.with_loop_scope(e.id,
|this| this.lower_block(body, false));
let body_expr = P(self.expr_block(body_block, ThinVec::new()));
- let body_stmt = respan(e.span, hir::StmtExpr(body_expr, self.next_id()));
+ let body_stmt = respan(e.span, hir::StmtExpr(body_expr, self.next_id().node_id));
let loop_block = P(self.block_all(e.span,
hir_vec![next_let,
// `[opt_ident]: loop { ... }`
let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
hir::LoopSource::ForLoop);
+ let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
let loop_expr = P(hir::Expr {
- id: self.lower_node_id(e.id),
+ id: node_id,
+ hir_id,
node: loop_expr,
span: e.span,
attrs: ThinVec::new(),
ExprKind::Mac(_) => panic!("Shouldn't exist here"),
};
+ let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
+
hir::Expr {
- id: self.lower_node_id(e.id),
+ id: node_id,
+ hir_id,
node: kind,
span: e.span,
attrs: e.attrs.clone(),
node: hir::StmtDecl(P(Spanned {
node: hir::DeclLocal(self.lower_local(l)),
span: s.span,
- }), self.lower_node_id(s.id)),
+ }), self.lower_node_id(s.id).node_id),
span: s.span,
},
StmtKind::Item(ref it) => {
node: hir::DeclItem(item_id),
span: s.span,
}), id.take()
- .map(|id| self.lower_node_id(id))
- .unwrap_or_else(|| self.next_id())),
+ .map(|id| self.lower_node_id(id).node_id)
+ .unwrap_or_else(|| self.next_id().node_id)),
span: s.span,
}).collect();
}
StmtKind::Expr(ref e) => {
Spanned {
node: hir::StmtExpr(P(self.lower_expr(e)),
- self.lower_node_id(s.id)),
+ self.lower_node_id(s.id).node_id),
span: s.span,
}
}
StmtKind::Semi(ref e) => {
Spanned {
node: hir::StmtSemi(P(self.lower_expr(e)),
- self.lower_node_id(s.id)),
+ self.lower_node_id(s.id).node_id),
span: s.span,
}
}
hir::Visibility::Restricted {
path: P(self.lower_path(id, path, ParamMode::Explicit, true)),
id: if let Some(owner) = explicit_owner {
- self.lower_node_id_with_owner(id, owner)
+ self.lower_node_id_with_owner(id, owner).node_id
} else {
- self.lower_node_id(id)
+ self.lower_node_id(id).node_id
}
}
}
}
fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> hir::Expr {
+ let LoweredNodeId { node_id, hir_id } = self.next_id();
hir::Expr {
- id: self.next_id(),
+ id: node_id,
+ hir_id,
node,
span,
attrs,
pat,
ty: None,
init: ex,
- id: self.next_id(),
+ id: self.next_id().node_id,
span: sp,
attrs: ThinVec::new(),
source,
});
let decl = respan(sp, hir::DeclLocal(local));
- respan(sp, hir::StmtDecl(P(decl), self.next_id()))
+ respan(sp, hir::StmtDecl(P(decl), self.next_id().node_id))
}
fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
fn block_all(&mut self, span: Span, stmts: hir::HirVec<hir::Stmt>, expr: Option<P<hir::Expr>>)
-> hir::Block {
+ let LoweredNodeId { node_id, hir_id } = self.next_id();
+
hir::Block {
stmts,
expr,
- id: self.next_id(),
+ id: node_id,
+ hir_id,
rules: hir::DefaultBlock,
span,
targeted_by_break: false,
fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingAnnotation)
-> P<hir::Pat> {
- let id = self.next_id();
+ let LoweredNodeId { node_id, hir_id } = self.next_id();
let parent_def = self.parent_def.unwrap();
let def_id = {
let defs = self.resolver.definitions();
let def_path_data = DefPathData::Binding(name);
- let def_index = defs
- .create_def_with_parent(parent_def, id, def_path_data, REGULAR_SPACE, Mark::root());
+ let def_index = defs.create_def_with_parent(parent_def,
+ node_id,
+ def_path_data,
+ REGULAR_SPACE,
+ Mark::root());
DefId::local(def_index)
};
P(hir::Pat {
- id,
+ id: node_id,
+ hir_id,
node: hir::PatKind::Binding(bm,
def_id,
Spanned {
}
fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
+ let LoweredNodeId { node_id, hir_id } = self.next_id();
P(hir::Pat {
- id: self.next_id(),
+ id: node_id,
+ hir_id,
node: pat,
span,
})
rule: hir::BlockCheckMode,
attrs: ThinVec<Attribute>)
-> hir::Expr {
- let id = self.next_id();
+ let LoweredNodeId { node_id, hir_id } = self.next_id();
+
let block = P(hir::Block {
rules: rule,
span,
- id,
+ id: node_id,
+ hir_id,
stmts,
expr: Some(expr),
targeted_by_break: false,
// The original ID is taken by the `PolyTraitRef`,
// so the `Ty` itself needs a different one.
- id = self.next_id();
+ id = self.next_id().node_id;
hir::TyTraitObject(hir_vec![principal], self.elided_lifetime(span))
} else {
fn elided_lifetime(&mut self, span: Span) -> hir::Lifetime {
hir::Lifetime {
- id: self.next_id(),
+ id: self.next_id().node_id,
span,
name: keywords::Invalid.name()
}
self.node_to_hir_id[node_id]
}
+ pub fn find_node_for_hir_id(&self, hir_id: hir::HirId) -> ast::NodeId {
+ self.node_to_hir_id.binary_search(&hir_id).unwrap()
+ }
+
/// Add a definition with a parent definition.
pub fn create_root_def(&mut self,
crate_name: &str,
}
}
+ #[inline]
pub fn definitions(&self) -> &Definitions {
&self.definitions
}
self.definitions.def_path(def_id.index)
}
+ #[inline]
pub fn local_def_id(&self, node: NodeId) -> DefId {
self.opt_local_def_id(node).unwrap_or_else(|| {
bug!("local_def_id: no entry for `{}`, which has a map of `{:?}`",
})
}
+ #[inline]
pub fn opt_local_def_id(&self, node: NodeId) -> Option<DefId> {
self.definitions.opt_local_def_id(node)
}
+ #[inline]
pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
self.definitions.as_local_node_id(def_id)
}
+ #[inline]
+ pub fn node_to_hir_id(&self, node_id: NodeId) -> HirId {
+ self.definitions.node_to_hir_id(node_id)
+ }
+
fn entry_count(&self) -> usize {
self.map.len()
}
pub const DUMMY_HIR_ID: HirId = HirId {
owner: CRATE_DEF_INDEX,
- local_id: ItemLocalId(!0)
+ local_id: DUMMY_ITEM_LOCAL_ID,
};
+pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId(!0);
+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
pub struct Lifetime {
pub id: NodeId,
/// without a semicolon, if any
pub expr: Option<P<Expr>>,
pub id: NodeId,
+ pub hir_id: HirId,
/// Distinguishes between `unsafe { ... }` and `{ ... }`
pub rules: BlockCheckMode,
pub span: Span,
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Pat {
pub id: NodeId,
+ pub hir_id: HirId,
pub node: PatKind,
pub span: Span,
}
pub span: Span,
pub node: Expr_,
pub attrs: ThinVec<Attribute>,
+ pub hir_id: HirId,
}
impl fmt::Debug for Expr {
pub struct Arg {
pub pat: P<Pat>,
pub id: NodeId,
+ pub hir_id: HirId,
}
/// Represents the header (not the body) of a function declaration
ref stmts,
ref expr,
id,
+ hir_id: _,
rules,
span,
targeted_by_break,
let hir::Pat {
id,
+ hir_id: _,
ref node,
ref span
} = *self;
hcx.while_hashing_hir_bodies(true, |hcx| {
let hir::Expr {
id,
+ hir_id: _,
ref span,
ref node,
ref attrs
impl_stable_hash_for!(struct hir::Arg {
pat,
- id
+ id,
+ hir_id
});
impl_stable_hash_for!(struct hir::Body {
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,
} = *self;
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
- ich::hash_stable_nodemap(hcx, hasher, type_dependent_defs);
+ ich::hash_stable_hashmap(hcx, hasher, type_dependent_defs, |_, item_local_id| {
+ *item_local_id
+ });
ich::hash_stable_nodemap(hcx, hasher, node_types);
ich::hash_stable_nodemap(hcx, hasher, node_substs);
ich::hash_stable_nodemap(hcx, hasher, adjustments);
impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
/// Used only by `rustc_typeck` during body type-checking/inference,
/// will initialize `in_progress_tables` with fresh `TypeckTables`.
- pub fn with_fresh_in_progress_tables(mut self) -> Self {
- self.fresh_tables = Some(RefCell::new(ty::TypeckTables::empty()));
+ pub fn with_fresh_in_progress_tables(mut self, table_owner: DefId) -> Self {
+ self.fresh_tables = Some(RefCell::new(ty::TypeckTables::empty(table_owner)));
self
}
use syntax_pos::{MultiSpan, Span};
use errors::DiagnosticBuilder;
use hir;
-use hir::def_id::LOCAL_CRATE;
+use hir::def_id::{DefId, LOCAL_CRATE};
use hir::intravisit as hir_visit;
use syntax::visit as ast_visit;
let mut cx = LateContext {
tcx,
- tables: &ty::TypeckTables::empty(),
+ tables: &ty::TypeckTables::empty(DefId::invalid()),
param_env: ty::ParamEnv::empty(Reveal::UserFacing),
access_levels,
lint_sess: LintSession::new(&tcx.sess.lint_store),
}
}
- fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
+ fn lookup_and_handle_method(&mut self, id: hir::ItemLocalId) {
self.check_def_id(self.tables.type_dependent_defs[&id].def_id());
}
fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, def: Def,
pats: &[codemap::Spanned<hir::FieldPat>]) {
+
+
let variant = match self.tables.node_id_to_type(lhs.id).sty {
ty::TyAdt(adt, _) => adt.variant_of_def(def),
_ => span_bug!(lhs.span, "non-ADT in struct pattern")
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node {
hir::ExprPath(ref qpath @ hir::QPath::TypeRelative(..)) => {
- let def = self.tables.qpath_def(qpath, expr.id);
+ let def = self.tables.qpath_def(qpath, expr.hir_id);
self.handle_definition(def);
}
hir::ExprMethodCall(..) => {
- self.lookup_and_handle_method(expr.id);
+ self.lookup_and_handle_method(expr.hir_id.local_id);
}
hir::ExprField(ref lhs, ref name) => {
self.handle_field_access(&lhs, name.node);
self.handle_field_pattern_match(pat, path.def, fields);
}
PatKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) => {
- let def = self.tables.qpath_def(qpath, pat.id);
+ let def = self.tables.qpath_def(qpath, pat.hir_id);
self.handle_definition(def);
}
_ => ()
let mut symbol_visitor = MarkSymbolVisitor {
worklist,
tcx,
- tables: &ty::TypeckTables::empty(),
+ tables: &ty::TypeckTables::empty(DefId::invalid()),
live_symbols: box FxHashSet(),
struct_has_extern_repr: false,
ignore_non_const_paths: false,
use syntax_pos::Span;
use hir::{self, PatKind};
use hir::def::Def;
+use hir::def_id::DefId;
use hir::intravisit::{self, FnKind, Visitor, NestedVisitorMap};
#[derive(Copy, Clone)]
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node {
hir::ExprMethodCall(..) => {
- let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
+ let def_id = self.tables.type_dependent_defs[&expr.hir_id.local_id].def_id();
let sig = self.tcx.fn_sig(def_id);
debug!("effect: method call case, signature is {:?}",
sig);
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut visitor = EffectCheckVisitor {
tcx,
- tables: &ty::TypeckTables::empty(),
+ tables: &ty::TypeckTables::empty(DefId::invalid()),
body_id: hir::BodyId { node_id: ast::CRATE_NODE_ID },
unsafe_context: UnsafeContext::new(SafeContext),
};
}
ty::TyError => { }
_ => {
- let def_id = self.mc.tables.type_dependent_defs[&call.id].def_id();
+ let def_id = self.mc.tables.type_dependent_defs[&call.hir_id.local_id].def_id();
match OverloadedCallType::from_method_id(self.tcx(), def_id) {
FnMutOverloadedCall => {
let call_scope_r = self.tcx().node_scope_region(call.id);
PatKind::Struct(ref qpath, ..) => qpath,
_ => return
};
- let def = mc.tables.qpath_def(qpath, pat.id);
+ let def = mc.tables.qpath_def(qpath, pat.hir_id);
match def {
Def::Variant(variant_did) |
Def::VariantCtor(variant_did, ..) => {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
let def = if let hir::ExprPath(ref qpath) = expr.node {
- self.tables.qpath_def(qpath, expr.id)
+ self.tables.qpath_def(qpath, expr.hir_id)
} else {
Def::Err
};
}
hir::ExprPath(ref qpath) => {
- let def = self.tables.qpath_def(qpath, expr.id);
+ let def = self.tables.qpath_def(qpath, expr.hir_id);
self.cat_def(expr.id, expr.span, expr_ty, def)
}
match pat.node {
PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
- let def = self.tables.qpath_def(qpath, pat.id);
+ let def = self.tables.qpath_def(qpath, pat.hir_id);
let (cmt, expected_len) = match def {
Def::Err => {
debug!("access to unresolvable pattern {:?}", pat);
PatKind::Struct(ref qpath, ref field_pats, _) => {
// {f1: p1, ..., fN: pN}
- let def = self.tables.qpath_def(qpath, pat.id);
+ let def = self.tables.qpath_def(qpath, pat.hir_id);
let cmt = match def {
Def::Err => {
debug!("access to unresolvable pattern {:?}", pat);
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
let def = match expr.node {
hir::ExprPath(ref qpath) => {
- Some(self.tables.qpath_def(qpath, expr.id))
+ Some(self.tables.qpath_def(qpath, expr.hir_id))
}
hir::ExprMethodCall(..) => {
- Some(self.tables.type_dependent_defs[&expr.id])
+ Some(self.tables.type_dependent_defs[&expr.hir_id.local_id])
}
_ => None
};
});
let mut reachable_context = ReachableContext {
tcx,
- tables: &ty::TypeckTables::empty(),
+ tables: &ty::TypeckTables::empty(DefId::invalid()),
reachable_symbols: NodeSet(),
worklist: Vec::new(),
any_library,
use errors::DiagnosticBuilder;
use session::Session;
use middle;
-use hir::TraitMap;
+use hir::{TraitMap};
use hir::def::{Def, ExportMap};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use hir::map as hir_map;
use ty::maps;
use ty::steal::Steal;
use ty::BindingMode;
-use util::nodemap::{NodeMap, NodeSet, DefIdSet};
+use util::nodemap::{NodeMap, NodeSet, DefIdSet, ItemLocalMap};
use util::nodemap::{FxHashMap, FxHashSet};
use rustc_data_structures::accumulate_vec::AccumulateVec;
#[derive(RustcEncodable, RustcDecodable)]
pub struct TypeckTables<'tcx> {
+ /// The HirId::owner all ItemLocalIds in this table are relative to.
+ pub local_id_root: DefId,
+
/// Resolved definitions for `<T>::X` associated paths and
/// method calls, including those of overloaded operators.
- pub type_dependent_defs: NodeMap<Def>,
+ pub 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
}
impl<'tcx> TypeckTables<'tcx> {
- pub fn empty() -> TypeckTables<'tcx> {
+ pub fn empty(local_id_root: DefId) -> TypeckTables<'tcx> {
TypeckTables {
- type_dependent_defs: NodeMap(),
+ local_id_root,
+ type_dependent_defs: ItemLocalMap(),
node_types: FxHashMap(),
node_substs: NodeMap(),
adjustments: NodeMap(),
}
/// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node.
- pub fn qpath_def(&self, qpath: &hir::QPath, id: NodeId) -> Def {
+ pub fn qpath_def(&self, qpath: &hir::QPath, id: hir::HirId) -> Def {
match *qpath {
hir::QPath::Resolved(_, ref path) => path.def,
hir::QPath::TypeRelative(..) => {
- self.type_dependent_defs.get(&id).cloned().unwrap_or(Def::Err)
+ self.validate_hir_id(id);
+ self.type_dependent_defs.get(&id.local_id).cloned().unwrap_or(Def::Err)
}
}
}
return false;
}
- match self.type_dependent_defs.get(&expr.id) {
+ self.validate_hir_id(expr.hir_id);
+ match self.type_dependent_defs.get(&expr.hir_id.local_id) {
Some(&Def::Method(_)) => true,
_ => false
}
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> {
self.upvar_capture_map[&upvar_id]
}
+
+ /// Validate that a NodeId can safely be converted to an ItemLocalId for
+ /// this table.
+ #[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)
+ });
+ }
+ }
+ }
+ }
}
impl<'tcx> CommonTypes<'tcx> {
#![allow(non_snake_case)]
use hir::def_id::DefId;
+use hir::ItemLocalId;
use syntax::ast;
pub use rustc_data_structures::fx::FxHashMap;
pub type NodeMap<T> = FxHashMap<ast::NodeId, T>;
pub type DefIdMap<T> = FxHashMap<DefId, T>;
+pub type ItemLocalMap<T> = FxHashMap<ItemLocalId, T>;
pub type NodeSet = FxHashSet<ast::NodeId>;
pub type DefIdSet = FxHashSet<DefId>;
pub fn NodeMap<T>() -> NodeMap<T> { FxHashMap() }
pub fn DefIdMap<T>() -> DefIdMap<T> { FxHashMap() }
+pub fn ItemLocalMap<T>() -> ItemLocalMap<T> { FxHashMap() }
pub fn NodeSet() -> NodeSet { FxHashSet() }
pub fn DefIdSet() -> DefIdSet { FxHashSet() }
}
hir::ExprPath(ref qpath) => {
let substs = cx.tables.node_substs(e.id).subst(tcx, cx.substs);
- match cx.tables.qpath_def(qpath, e.id) {
+ match cx.tables.qpath_def(qpath, e.hir_id) {
Def::Const(def_id) |
Def::AssociatedConst(def_id) => {
match tcx.at(e.span).const_eval(cx.param_env.and((def_id, substs))) {
}
PatKind::Path(ref qpath) => {
- return self.lower_path(qpath, pat.id, pat.id, pat.span);
+ return self.lower_path(qpath, (pat.id, pat.hir_id), pat.id, pat.span);
}
PatKind::Ref(ref subpattern, _) |
}
PatKind::TupleStruct(ref qpath, ref subpatterns, ddpos) => {
- let def = self.tables.qpath_def(qpath, pat.id);
+ let def = self.tables.qpath_def(qpath, pat.hir_id);
let adt_def = match ty.sty {
ty::TyAdt(adt_def, _) => adt_def,
_ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT"),
}
PatKind::Struct(ref qpath, ref fields, _) => {
- let def = self.tables.qpath_def(qpath, pat.id);
+ let def = self.tables.qpath_def(qpath, pat.hir_id);
let adt_def = match ty.sty {
ty::TyAdt(adt_def, _) => adt_def,
_ => {
fn lower_path(&mut self,
qpath: &hir::QPath,
- id: ast::NodeId,
+ (id, hir_id): (ast::NodeId, hir::HirId),
pat_id: ast::NodeId,
span: Span)
-> Pattern<'tcx> {
let ty = self.tables.node_id_to_type(id);
- let def = self.tables.qpath_def(qpath, id);
+ let def = self.tables.qpath_def(qpath, hir_id);
let kind = match def {
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
let substs = self.tables.node_substs(id);
_ => bug!()
};
let ty = self.tables.node_id_to_type(callee.id);
- let def = self.tables.qpath_def(qpath, callee.id);
+ let def = self.tables.qpath_def(qpath, callee.hir_id);
match def {
Def::Fn(..) | Def::Method(..) => self.lower_lit(expr),
_ => {
}
hir::ExprStruct(ref qpath, ref fields, None) => {
- let def = self.tables.qpath_def(qpath, expr.id);
+ let def = self.tables.qpath_def(qpath, expr.hir_id);
let adt_def = match pat_ty.sty {
ty::TyAdt(adt_def, _) => adt_def,
_ => {
}
hir::ExprPath(ref qpath) => {
- return self.lower_path(qpath, expr.id, pat_id, span);
+ return self.lower_path(qpath, (expr.id, expr.hir_id), pat_id, span);
}
_ => self.lower_lit(expr)
}
}
+impl<I: Idx, T: Ord> IndexVec<I, T> {
+ #[inline]
+ pub fn binary_search(&self, value: &T) -> Result<I, I> {
+ match self.raw.binary_search(value) {
+ Ok(i) => Ok(Idx::new(i)),
+ Err(i) => Err(Idx::new(i)),
+ }
+ }
+}
+
impl<I: Idx, T> Index<I> for IndexVec<I, T> {
type Output = T;
use std::path::Path;
use std::str::FromStr;
+use rustc::hir::def_id::DefId;
use rustc::hir::map as hir_map;
use rustc::hir::map::blocks;
use rustc::hir;
arenas,
id,
|tcx, _, _, _| {
- let empty_tables = ty::TypeckTables::empty();
+ let empty_tables = ty::TypeckTables::empty(DefId::invalid());
let annotation = TypedAnnotation {
tcx: tcx,
tables: Cell::new(&empty_tables)
match cx.tcx.hir.get(id) {
hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
let def = if let hir::ExprPath(ref qpath) = callee.node {
- cx.tables.qpath_def(qpath, callee.id)
+ cx.tables.qpath_def(qpath, callee.hir_id)
} else {
return false;
};
// Check for method calls and overloaded operators.
if cx.tables.is_method_call(expr) {
- let def_id = cx.tables.type_dependent_defs[&id].def_id();
+ let local_id = cx.tcx.hir.definitions().node_to_hir_id(id).local_id;
+ let def_id = cx.tables.type_dependent_defs[&local_id].def_id();
let substs = cx.tables.node_substs(id);
if method_call_refers_to_method(cx, method, def_id, substs, id) {
return true;
match expr.node {
hir::ExprCall(ref callee, _) => {
let def = if let hir::ExprPath(ref qpath) = callee.node {
- cx.tables.qpath_def(qpath, callee.id)
+ cx.tables.qpath_def(qpath, callee.hir_id)
} else {
return false;
};
expr: &hir::Expr)
-> Option<(&'tcx ty::TypeVariants<'tcx>, &'tcx ty::TypeVariants<'tcx>)> {
let def = if let hir::ExprPath(ref qpath) = expr.node {
- cx.tables.qpath_def(qpath, expr.id)
+ cx.tables.qpath_def(qpath, expr.hir_id)
} else {
return None;
};
}
hir::ExprPath(ref qpath) => {
- let def = cx.tables().qpath_def(qpath, expr.id);
+ let def = cx.tables().qpath_def(qpath, expr.hir_id);
convert_path_expr(cx, expr, def)
}
-> Expr<'tcx> {
let temp_lifetime = cx.region_maps.temporary_scope(expr.id);
let (def_id, substs) = custom_callee.unwrap_or_else(|| {
- (cx.tables().type_dependent_defs[&expr.id].def_id(),
+ cx.tables().validate_hir_id(expr.hir_id);
+ (cx.tables().type_dependent_defs[&expr.hir_id.local_id].def_id(),
cx.tables().node_substs(expr.id))
});
Expr {
}
}
hir::ExprPath(ref qpath) => {
- let def = v.tables.qpath_def(qpath, e.id);
+ let def = v.tables.qpath_def(qpath, e.hir_id);
match def {
Def::VariantCtor(..) | Def::StructCtor(..) |
Def::Fn(..) | Def::Method(..) => {}
}
// The callee is an arbitrary expression, it doesn't necessarily have a definition.
let def = if let hir::ExprPath(ref qpath) = callee.node {
- v.tables.qpath_def(qpath, callee.id)
+ v.tables.qpath_def(qpath, callee.hir_id)
} else {
Def::Err
};
}
}
hir::ExprMethodCall(..) => {
- let def_id = v.tables.type_dependent_defs[&e.id].def_id();
+ v.tables.validate_hir_id(e.hir_id);
+ let def_id = v.tables.type_dependent_defs[&e.hir_id.local_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
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx.hir.krate().visit_all_item_likes(&mut CheckCrateVisitor {
tcx: tcx,
- tables: &ty::TypeckTables::empty(),
+ tables: &ty::TypeckTables::empty(DefId::invalid()),
in_fn: false,
promotable: false,
mut_rvalue_borrows: NodeSet(),
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
current_item: ast::NodeId,
+ empty_tables: &'a ty::TypeckTables<'tcx>,
}
impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
}
}
+// Set the correct TypeckTables for the given `item_id` (or an empty table if
+// there is no TypeckTables for the item).
+fn update_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ item_id: ast::NodeId,
+ tables: &mut &'a ty::TypeckTables<'tcx>,
+ empty_tables: &'a ty::TypeckTables<'tcx>)
+ -> &'a ty::TypeckTables<'tcx> {
+ let def_id = tcx.hir.local_def_id(item_id);
+
+ if tcx.has_typeck_tables(def_id) {
+ replace(tables, tcx.typeck_tables_of(def_id))
+ } else {
+ replace(tables, empty_tables)
+ }
+}
+
impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
/// We want to visit items in the context of their containing
/// module and so forth, so supply a crate for doing a deep walk.
fn visit_item(&mut self, item: &'tcx hir::Item) {
let orig_current_item = replace(&mut self.current_item, item.id);
+ let orig_tables = update_tables(self.tcx, item.id, &mut self.tables, self.empty_tables);
intravisit::walk_item(self, item);
self.current_item = orig_current_item;
+ self.tables = orig_tables;
+ }
+
+ fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
+ let orig_tables = update_tables(self.tcx, ti.id, &mut self.tables, self.empty_tables);
+ intravisit::walk_trait_item(self, ti);
+ self.tables = orig_tables;
+ }
+
+ fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
+ let orig_tables = update_tables(self.tcx, ii.id, &mut self.tables, self.empty_tables);
+ intravisit::walk_impl_item(self, ii);
+ self.tables = orig_tables;
}
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node {
hir::ExprStruct(ref qpath, ref fields, ref base) => {
- let def = self.tables.qpath_def(qpath, expr.id);
+ let def = self.tables.qpath_def(qpath, expr.hir_id);
let adt = self.tables.expr_ty(expr).ty_adt_def().unwrap();
let variant = adt.variant_of_def(def);
if let Some(ref base) = *base {
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
match pat.node {
PatKind::Struct(ref qpath, ref fields, _) => {
- let def = self.tables.qpath_def(qpath, pat.id);
+ let def = self.tables.qpath_def(qpath, pat.hir_id);
let adt = self.tables.pat_ty(pat).ty_adt_def().unwrap();
let variant = adt.variant_of_def(def);
for field in fields {
tables: &'a ty::TypeckTables<'tcx>,
current_item: DefId,
span: Span,
+ empty_tables: &'a ty::TypeckTables<'tcx>,
}
impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
}
hir::ExprMethodCall(_, span, _) => {
// Method calls have to be checked specially.
- let def_id = self.tables.type_dependent_defs[&expr.id].def_id();
+ self.tables.validate_hir_id(expr.hir_id);
+ let def_id = self.tables.type_dependent_defs[&expr.hir_id.local_id].def_id();
self.span = span;
if self.tcx.type_of(def_id).visit_with(self) {
return;
// Inherent associated constants don't have self type in substs,
// we have to check it additionally.
if let hir::QPath::TypeRelative(..) = *qpath {
- if let Some(def) = self.tables.type_dependent_defs.get(&id).cloned() {
+ 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(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) {
// Check types in item interfaces
fn visit_item(&mut self, item: &'tcx hir::Item) {
let orig_current_item = self.current_item;
+ let orig_tables = update_tables(self.tcx,
+ item.id,
+ &mut self.tables,
+ self.empty_tables);
match item.node {
hir::ItemExternCrate(..) | hir::ItemMod(..) |
self.current_item = self.tcx.hir.local_def_id(item.id);
intravisit::walk_item(self, item);
+ self.tables = orig_tables;
self.current_item = orig_current_item;
}
+
+ fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) {
+ let orig_tables = update_tables(self.tcx, ti.id, &mut self.tables, self.empty_tables);
+ intravisit::walk_trait_item(self, ti);
+ self.tables = orig_tables;
+ }
+
+ fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) {
+ let orig_tables = update_tables(self.tcx, ii.id, &mut self.tables, self.empty_tables);
+ intravisit::walk_impl_item(self, ii);
+ self.tables = orig_tables;
+ }
}
impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
let krate = tcx.hir.krate();
+ let empty_tables = ty::TypeckTables::empty(DefId::invalid());
+
+
// Check privacy of names not checked in previous compilation stages.
let mut visitor = NamePrivacyVisitor {
tcx: tcx,
- tables: &ty::TypeckTables::empty(),
+ tables: &empty_tables,
current_item: CRATE_NODE_ID,
+ empty_tables: &empty_tables,
};
intravisit::walk_crate(&mut visitor, krate);
// inferred types of expressions and patterns.
let mut visitor = TypePrivacyVisitor {
tcx: tcx,
- tables: &ty::TypeckTables::empty(),
+ tables: &empty_tables,
current_item: DefId::local(CRATE_DEF_INDEX),
span: krate.span,
+ empty_tables: &empty_tables,
};
intravisit::walk_crate(&mut visitor, krate);
}
}
ast::ExprKind::MethodCall(..) => {
- let method_id = self.tables.type_dependent_defs[&expr.id].def_id();
+ 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 (def_id, decl_id) = match self.tcx.associated_item(method_id).container {
ty::ImplContainer(_) => (Some(method_id), None),
ty::TraitContainer(_) => (None, Some(method_id)),
Node::NodePat(&hir::Pat { node: hir::PatKind::Path(ref qpath), .. }) |
Node::NodePat(&hir::Pat { node: hir::PatKind::Struct(ref qpath, ..), .. }) |
Node::NodePat(&hir::Pat { node: hir::PatKind::TupleStruct(ref qpath, ..), .. }) => {
- self.tables.qpath_def(qpath, id)
+ let hir_id = self.tcx.hir.node_to_hir_id(id);
+ self.tables.qpath_def(qpath, hir_id)
}
Node::NodeLocal(&hir::Pat { node: hir::PatKind::Binding(_, def_id, ..), .. }) => {
let save_ctxt = SaveContext {
tcx: tcx,
- tables: &ty::TypeckTables::empty(),
+ tables: &ty::TypeckTables::empty(DefId::invalid()),
analysis: analysis,
span_utils: SpanUtils::new(&tcx.sess),
config: find_config(config),
if let hir::ExprCall(ref expr, _) = call_expr.node {
let def = if let hir::ExprPath(ref qpath) = expr.node {
- self.tables.borrow().qpath_def(qpath, expr.id)
+ self.tables.borrow().qpath_def(qpath, expr.hir_id)
} else {
Def::Err
};
TupleArgumentsFlag::TupleArguments,
expected);
- self.write_method_call(call_expr.id, method_callee);
+ self.write_method_call((call_expr.id, call_expr.hir_id), method_callee);
output_type
}
}
adjustments.extend(autoref);
fcx.apply_adjustments(self.callee_expr, adjustments);
- fcx.write_method_call(self.call_expr.id, method_callee);
+ fcx.write_method_call((self.call_expr.id, self.call_expr.hir_id),
+ method_callee);
}
None => {
span_bug!(self.call_expr.span,
None => return self.tcx.sess.delay_span_bug(expr.span, "re-trying op failed")
};
debug!("convert_lvalue_op_to_mutable: method={:?}", method);
- self.write_method_call(expr.id, method);
+ self.write_method_call((expr.id, expr.hir_id), method);
let (region, mutbl) = if let ty::TyRef(r, mt) = method.sig.inputs()[0].sty {
(r, mt.mutbl)
impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId)
-> InheritedBuilder<'a, 'gcx, 'tcx> {
+ let hir_id_root = if def_id.is_local() {
+ let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+ let hir_id = tcx.hir.definitions().node_to_hir_id(node_id);
+ DefId::local(hir_id.owner)
+ } else {
+ def_id
+ };
+
InheritedBuilder {
- infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(),
+ infcx: tcx.infer_ctxt().with_fresh_in_progress_tables(hir_id_root),
def_id,
}
}
});
let body = tcx.hir.body(body_id);
- Inherited::build(tcx, def_id).enter(|inh| {
+ let tables = Inherited::build(tcx, def_id).enter(|inh| {
let param_env = tcx.param_env(def_id);
let fcx = if let Some(decl) = fn_decl {
let fn_sig = tcx.fn_sig(def_id);
}
fcx.resolve_type_vars_in_body(body)
- })
+ });
+
+ // Consistency check our TypeckTables instance can hold all ItemLocalIds
+ // it will need to hold.
+ assert_eq!(tables.local_id_root,
+ DefId::local(tcx.hir.definitions().node_to_hir_id(id).owner));
+ tables
}
fn check_abi<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, abi: Abi) {
}
}
- pub fn write_method_call(&self, node_id: ast::NodeId, method: MethodCallee<'tcx>) {
- self.tables.borrow_mut().type_dependent_defs.insert(node_id, Def::Method(method.def_id));
+ // The NodeId and the ItemLocalId must identify the same item. We just pass
+ // both of them for consistency checking.
+ pub fn write_method_call(&self,
+ (node_id, hir_id): (ast::NodeId, 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.write_substs(node_id, method.substs);
}
}
self.apply_adjustments(base_expr, adjustments);
- self.write_method_call(expr.id, method);
+ self.write_method_call((expr.id, expr.hir_id), method);
(input_ty, self.make_overloaded_lvalue_return_type(method).ty)
});
if result.is_some() {
expr,
rcvr) {
Ok(method) => {
- self.write_method_call(expr.id, method);
+ self.write_method_call((expr.id, expr.hir_id), method);
Ok(method)
}
Err(error) => {
}]);
}
oprnd_t = self.make_overloaded_lvalue_return_type(method).ty;
- self.write_method_call(expr.id, method);
+ self.write_method_call((expr.id, expr.hir_id), method);
} else {
type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
"type `{}` cannot be dereferenced",
ty, def, segment);
// Write back the new resolution.
- self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
+ 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);
(def, ty)
}
};
// Write back the new resolution.
- self.tables.borrow_mut().type_dependent_defs.insert(node_id, def);
+ 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);
(def, Some(ty), slice::ref_slice(&**item_segment))
}
.or_insert(vec![]).push(autoref);
}
}
- self.write_method_call(expr.id, method);
+ self.write_method_call((expr.id, expr.hir_id), method);
method.sig.output()
}
assert!(op.is_by_value());
match self.lookup_op_method(operand_ty, &[], Op::Unary(op, ex.span)) {
Ok(method) => {
- self.write_method_call(ex.id, method);
+ self.write_method_call((ex.id, ex.hir_id), method);
method.sig.output()
}
Err(()) => {
use check::FnCtxt;
use rustc::hir;
+use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::infer::{InferCtxt};
use rustc::ty::{self, Ty, TyCtxt};
let mut wbcx = WritebackCx::new(self, body);
for arg in &body.arguments {
- wbcx.visit_node_id(arg.pat.span, arg.id);
+ wbcx.visit_node_id(arg.pat.span, (arg.id, arg.hir_id));
}
wbcx.visit_body(body);
wbcx.visit_upvar_borrow_map();
impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
fn new(fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>, body: &'gcx hir::Body)
- -> WritebackCx<'cx, 'gcx, 'tcx> {
+ -> WritebackCx<'cx, 'gcx, 'tcx>
+ {
+ let owner = fcx.tcx.hir.definitions().node_to_hir_id(body.id().node_id);
+
WritebackCx {
fcx: fcx,
- tables: ty::TypeckTables::empty(),
+ tables: ty::TypeckTables::empty(DefId::local(owner.owner)),
body: body
}
}
if inner_ty.is_scalar() {
let mut tables = self.fcx.tables.borrow_mut();
- tables.type_dependent_defs.remove(&e.id);
+ tables.validate_hir_id(e.hir_id);
+ tables.type_dependent_defs.remove(&e.hir_id.local_id);
tables.node_substs.remove(&e.id);
}
}
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
let mut tables = self.fcx.tables.borrow_mut();
- tables.type_dependent_defs.remove(&e.id);
+ tables.validate_hir_id(e.hir_id);
+ tables.type_dependent_defs.remove(&e.hir_id.local_id);
tables.node_substs.remove(&e.id);
match e.node {
fn visit_expr(&mut self, e: &'gcx hir::Expr) {
self.fix_scalar_builtin_expr(e);
- self.visit_node_id(e.span, e.id);
+ self.visit_node_id(e.span, (e.id, e.hir_id));
if let hir::ExprClosure(_, _, body, _) = e.node {
let body = self.fcx.tcx.hir.body(body);
for arg in &body.arguments {
- self.visit_node_id(e.span, arg.id);
+ self.visit_node_id(e.span, (arg.id, arg.hir_id));
}
self.visit_body(body);
}
fn visit_block(&mut self, b: &'gcx hir::Block) {
- self.visit_node_id(b.span, b.id);
+ self.visit_node_id(b.span, (b.id, b.hir_id));
intravisit::walk_block(self, b);
}
_ => {}
};
- self.visit_node_id(p.span, p.id);
+ self.visit_node_id(p.span, (p.id, p.hir_id));
intravisit::walk_pat(self, p);
}
}
}
- fn visit_node_id(&mut self, span: Span, node_id: ast::NodeId) {
- // Export associated path extensions and method resultions.
- if let Some(def) = self.fcx.tables.borrow_mut().type_dependent_defs.remove(&node_id) {
- self.tables.type_dependent_defs.insert(node_id, def);
+ fn visit_node_id(&mut self,
+ span: Span,
+ (node_id, hir_id): (ast::NodeId, 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);
+ }
}
// Resolve any borrowings for the node with id `node_id`