Make TypeckTables::type_dependent_defs use ItemLocalId instead of NodeId.

This commit is contained in:
Michael Woerister 2017-08-04 09:49:40 +02:00
parent 9868352b95
commit 783ccc443b
31 changed files with 387 additions and 152 deletions

View File

@ -201,4 +201,11 @@ impl DefId {
pub fn is_local(&self) -> bool {
self.krate == LOCAL_CRATE
}
pub fn invalid() -> DefId {
DefId {
krate: INVALID_CRATE,
index: CRATE_DEF_INDEX,
}
}
}

View File

@ -155,6 +155,11 @@ enum ParamMode {
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
@ -278,11 +283,14 @@ impl<'a> LoweringContext<'a> {
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;
@ -291,12 +299,22 @@ impl<'a> LoweringContext<'a> {
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 {
// Generate a new HirId
self.node_id_to_hir_id[ast_node_id] = alloc_hir_id(self);
}
let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
ast_node_id
if existing_hir_id == hir::DUMMY_HIR_ID {
// Generate a new HirId
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,
}
}
}
fn with_hir_id_owner<F>(&mut self, owner: NodeId, f: F)
@ -323,7 +341,7 @@ impl<'a> LoweringContext<'a> {
/// 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()
@ -340,7 +358,7 @@ impl<'a> LoweringContext<'a> {
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)
@ -375,7 +393,7 @@ impl<'a> LoweringContext<'a> {
id
}
fn next_id(&mut self) -> NodeId {
fn next_id(&mut self) -> LoweredNodeId {
self.lower_node_id(self.sess.next_node_id())
}
@ -517,7 +535,7 @@ impl<'a> LoweringContext<'a> {
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)
};
@ -534,7 +552,7 @@ impl<'a> LoweringContext<'a> {
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())
}
@ -557,7 +575,7 @@ impl<'a> LoweringContext<'a> {
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,
@ -594,7 +612,7 @@ impl<'a> LoweringContext<'a> {
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);
}
@ -645,7 +663,7 @@ impl<'a> LoweringContext<'a> {
};
P(hir::Ty {
id: self.lower_node_id(t.id),
id: self.lower_node_id(t.id).node_id,
node: kind,
span: t.span,
})
@ -758,7 +776,7 @@ impl<'a> LoweringContext<'a> {
// 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))
};
@ -782,7 +800,7 @@ impl<'a> LoweringContext<'a> {
}
// 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);
}
@ -887,7 +905,7 @@ impl<'a> LoweringContext<'a> {
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))),
@ -905,8 +923,10 @@ impl<'a> LoweringContext<'a> {
}
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),
}
}
@ -969,7 +989,7 @@ impl<'a> LoweringContext<'a> {
}
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)),
@ -987,7 +1007,7 @@ impl<'a> LoweringContext<'a> {
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,
}
@ -1059,7 +1079,7 @@ impl<'a> LoweringContext<'a> {
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))
@ -1098,7 +1118,7 @@ impl<'a> LoweringContext<'a> {
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,
@ -1114,16 +1134,16 @@ impl<'a> LoweringContext<'a> {
.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),
}
}
@ -1134,7 +1154,7 @@ impl<'a> LoweringContext<'a> {
};
hir::TraitRef {
path,
ref_id: self.lower_node_id(p.ref_id),
ref_id: self.lower_node_id(p.ref_id).node_id,
}
}
@ -1149,7 +1169,7 @@ impl<'a> LoweringContext<'a> {
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
@ -1198,8 +1218,11 @@ impl<'a> LoweringContext<'a> {
}
}
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),
@ -1249,7 +1272,7 @@ impl<'a> LoweringContext<'a> {
hir::Visibility::Restricted {
path: path.clone(),
// We are allocating a new NodeId here
id: this.next_id(),
id: this.next_id().node_id,
}
}
};
@ -1387,7 +1410,7 @@ impl<'a> LoweringContext<'a> {
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 {
@ -1448,7 +1471,7 @@ impl<'a> LoweringContext<'a> {
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),
@ -1540,7 +1563,7 @@ impl<'a> LoweringContext<'a> {
});
Some(hir::Item {
id: self.lower_node_id(i.id),
id: self.lower_node_id(i.id).node_id,
name,
attrs,
node,
@ -1552,7 +1575,7 @@ impl<'a> LoweringContext<'a> {
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 {
@ -1630,8 +1653,11 @@ impl<'a> LoweringContext<'a> {
}
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) => {
@ -1813,7 +1839,7 @@ impl<'a> LoweringContext<'a> {
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);
@ -1883,11 +1909,15 @@ impl<'a> LoweringContext<'a> {
// 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,
@ -1986,8 +2016,11 @@ impl<'a> LoweringContext<'a> {
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 {
@ -2234,7 +2267,7 @@ impl<'a> LoweringContext<'a> {
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));
@ -2254,7 +2287,7 @@ impl<'a> LoweringContext<'a> {
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,
@ -2266,8 +2299,10 @@ impl<'a> LoweringContext<'a> {
// `[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(),
@ -2406,8 +2441,11 @@ impl<'a> LoweringContext<'a> {
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(),
@ -2420,7 +2458,7 @@ impl<'a> LoweringContext<'a> {
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) => {
@ -2431,22 +2469,22 @@ impl<'a> LoweringContext<'a> {
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,
}
}
@ -2477,9 +2515,9 @@ impl<'a> LoweringContext<'a> {
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
}
}
}
@ -2621,8 +2659,10 @@ impl<'a> LoweringContext<'a> {
}
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,
@ -2639,13 +2679,13 @@ impl<'a> LoweringContext<'a> {
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>)
@ -2665,10 +2705,13 @@ impl<'a> LoweringContext<'a> {
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,
@ -2712,18 +2755,22 @@ impl<'a> LoweringContext<'a> {
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 {
@ -2740,8 +2787,10 @@ impl<'a> LoweringContext<'a> {
}
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,
})
@ -2770,11 +2819,13 @@ impl<'a> LoweringContext<'a> {
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,
@ -2799,7 +2850,7 @@ impl<'a> LoweringContext<'a> {
// 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 {
@ -2813,7 +2864,7 @@ impl<'a> LoweringContext<'a> {
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()
}

View File

@ -465,6 +465,10 @@ impl Definitions {
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,

View File

@ -357,6 +357,7 @@ impl<'hir> Map<'hir> {
}
}
#[inline]
pub fn definitions(&self) -> &Definitions {
&self.definitions
}
@ -377,6 +378,7 @@ impl<'hir> Map<'hir> {
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 `{:?}`",
@ -384,14 +386,21 @@ impl<'hir> Map<'hir> {
})
}
#[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()
}

View File

@ -129,9 +129,11 @@ pub const CRATE_HIR_ID: HirId = HirId {
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,
@ -547,6 +549,7 @@ pub struct Block {
/// 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,
@ -560,6 +563,7 @@ pub struct Block {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub struct Pat {
pub id: NodeId,
pub hir_id: HirId,
pub node: PatKind,
pub span: Span,
}
@ -986,6 +990,7 @@ pub struct Expr {
pub span: Span,
pub node: Expr_,
pub attrs: ThinVec<Attribute>,
pub hir_id: HirId,
}
impl fmt::Debug for Expr {
@ -1423,6 +1428,7 @@ pub struct InlineAsm {
pub struct Arg {
pub pat: P<Pat>,
pub id: NodeId,
pub hir_id: HirId,
}
/// Represents the header (not the body) of a function declaration

View File

@ -359,6 +359,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B
ref stmts,
ref expr,
id,
hir_id: _,
rules,
span,
targeted_by_break,
@ -423,6 +424,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::P
let hir::Pat {
id,
hir_id: _,
ref node,
ref span
} = *self;
@ -551,6 +553,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::E
hcx.while_hashing_hir_bodies(true, |hcx| {
let hir::Expr {
id,
hir_id: _,
ref span,
ref node,
ref attrs
@ -1021,7 +1024,8 @@ impl_stable_hash_for!(enum hir::Stmt_ {
impl_stable_hash_for!(struct hir::Arg {
pat,
id
id,
hir_id
});
impl_stable_hash_for!(struct hir::Body {

View File

@ -618,6 +618,7 @@ for ty::TypeckTables<'gcx> {
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,
@ -637,7 +638,9 @@ for ty::TypeckTables<'gcx> {
} = *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);

View File

@ -358,8 +358,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
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
}

View File

@ -43,7 +43,7 @@ use syntax::ast;
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;
@ -986,7 +986,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
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),

View File

@ -94,7 +94,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}
}
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());
}
@ -119,6 +119,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
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")
@ -235,11 +237,11 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
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);
@ -282,7 +284,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
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);
}
_ => ()
@ -425,7 +427,7 @@ fn find_live<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
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,

View File

@ -19,6 +19,7 @@ use syntax::ast;
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)]
@ -165,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.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);
@ -262,7 +263,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
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),
};

View File

@ -537,7 +537,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
}
ty::TyError => { }
_ => {
let def_id = self.mc.tables.type_dependent_defs[&call.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);
@ -863,7 +863,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
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, ..) => {

View File

@ -146,7 +146,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
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
};

View File

@ -604,7 +604,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
}
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)
}
@ -1124,7 +1124,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
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);
@ -1161,7 +1161,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
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);

View File

@ -107,10 +107,10 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
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
};
@ -375,7 +375,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) ->
});
let mut reachable_context = ReachableContext {
tcx,
tables: &ty::TypeckTables::empty(),
tables: &ty::TypeckTables::empty(DefId::invalid()),
reachable_symbols: NodeSet(),
worklist: Vec::new(),
any_library,

View File

@ -14,7 +14,7 @@ use dep_graph::DepGraph;
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;
@ -42,7 +42,7 @@ use ty::inhabitedness::DefIdForest;
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;
@ -209,9 +209,12 @@ pub struct CommonTypes<'tcx> {
#[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
@ -271,9 +274,10 @@ pub struct TypeckTables<'tcx> {
}
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(),
@ -291,11 +295,12 @@ impl<'tcx> TypeckTables<'tcx> {
}
/// 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)
}
}
}
@ -373,7 +378,8 @@ impl<'tcx> TypeckTables<'tcx> {
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
}
@ -382,6 +388,30 @@ impl<'tcx> TypeckTables<'tcx> {
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> {

View File

@ -13,6 +13,7 @@
#![allow(non_snake_case)]
use hir::def_id::DefId;
use hir::ItemLocalId;
use syntax::ast;
pub use rustc_data_structures::fx::FxHashMap;
@ -20,12 +21,14 @@ pub use rustc_data_structures::fx::FxHashSet;
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() }

View File

@ -276,7 +276,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
}
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))) {

View File

@ -321,7 +321,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
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, _) |
@ -417,7 +417,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
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"),
@ -436,7 +436,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
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,
_ => {
@ -590,12 +590,12 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
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);
@ -696,7 +696,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
_ => 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),
_ => {
@ -712,7 +712,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
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,
_ => {
@ -755,7 +755,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
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)

View File

@ -196,6 +196,16 @@ impl<I: Idx, T: Clone> IndexVec<I, T> {
}
}
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;

View File

@ -45,6 +45,7 @@ use std::option;
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;
@ -232,7 +233,7 @@ impl PpSourceMode {
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)

View File

@ -896,7 +896,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
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;
};
@ -934,7 +934,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
// 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;
@ -945,7 +946,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
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;
};
@ -1179,7 +1180,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
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;
};

View File

@ -450,7 +450,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
}
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)
}
@ -580,7 +580,8 @@ 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().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 {

View File

@ -329,7 +329,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
}
}
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(..) => {}
@ -365,7 +365,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
}
// 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
};
@ -387,7 +387,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
}
}
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
@ -471,7 +472,7 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp
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(),

View File

@ -473,6 +473,7 @@ struct NamePrivacyVisitor<'a, 'tcx: 'a> {
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> {
@ -489,6 +490,22 @@ 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.
@ -505,14 +522,28 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
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 {
@ -539,7 +570,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
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 {
@ -564,6 +595,7 @@ struct TypePrivacyVisitor<'a, 'tcx: 'a> {
tables: &'a ty::TypeckTables<'tcx>,
current_item: DefId,
span: Span,
empty_tables: &'a ty::TypeckTables<'tcx>,
}
impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
@ -716,7 +748,8 @@ impl<'a, 'tcx> Visitor<'tcx> for 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;
@ -732,7 +765,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
// 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) {
@ -770,6 +805,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
// 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(..) |
@ -829,8 +868,21 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
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> {
@ -1606,11 +1658,15 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, '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);
@ -1618,9 +1674,10 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// 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);

View File

@ -550,7 +550,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}
}
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)),
@ -586,7 +587,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
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, ..), .. }) => {
@ -975,7 +977,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(tcx: TyCtxt<'l, 'tcx, 'tcx>,
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),

View File

@ -222,7 +222,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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
};
@ -314,7 +314,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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
}
}
@ -364,7 +364,8 @@ impl<'a, 'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> {
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,

View File

@ -513,7 +513,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
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)

View File

@ -572,8 +572,16 @@ pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
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,
}
}
@ -840,7 +848,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
});
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);
@ -887,7 +895,13 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
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) {
@ -1804,8 +1818,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
}
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);
}
@ -2254,7 +2276,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
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() {
@ -2794,7 +2816,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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) => {
@ -3499,7 +3521,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}]);
}
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",
@ -4000,7 +4022,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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)
}
@ -4041,7 +4066,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
// 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))
}

View File

@ -214,7 +214,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
.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()
}
@ -340,7 +340,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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(()) => {

View File

@ -14,6 +14,7 @@
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};
@ -34,7 +35,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
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();
@ -74,10 +75,13 @@ struct WritebackCx<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
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
}
}
@ -105,7 +109,8 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
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);
}
}
@ -119,7 +124,8 @@ 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.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 {
@ -157,12 +163,12 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
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);
@ -172,7 +178,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
}
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);
}
@ -186,7 +192,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
_ => {}
};
self.visit_node_id(p.span, p.id);
self.visit_node_id(p.span, (p.id, p.hir_id));
intravisit::walk_pat(self, p);
}
@ -277,10 +283,17 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}
}
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`