Use ItemLocalId as key for node_types, node_substs, and adjustments in TypeckTables.

This commit is contained in:
Michael Woerister 2017-08-07 14:43:43 +02:00
parent 783ccc443b
commit 7f2423eede
35 changed files with 282 additions and 208 deletions

View File

@ -904,8 +904,10 @@ impl<'a> LoweringContext<'a> {
}
fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(l.id);
P(hir::Local {
id: self.lower_node_id(l.id).node_id,
id: node_id,
hir_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))),
@ -2675,11 +2677,14 @@ impl<'a> LoweringContext<'a> {
pat: P<hir::Pat>,
source: hir::LocalSource)
-> hir::Stmt {
let LoweredNodeId { node_id, hir_id } = self.next_id();
let local = P(hir::Local {
pat,
ty: None,
init: ex,
id: self.next_id().node_id,
id: node_id,
hir_id,
span: sp,
attrs: ThinVec::new(),
source,

View File

@ -901,6 +901,7 @@ pub struct Local {
/// Initializer expression to set the value, if any
pub init: Option<P<Expr>>,
pub id: NodeId,
pub hir_id: HirId,
pub span: Span,
pub attrs: ThinVec<Attribute>,
pub source: LocalSource,

View File

@ -14,7 +14,7 @@ use hir::map::DefPathHash;
use ich::{self, CachingCodemapView};
use session::config::DebugInfoLevel::NoDebugInfo;
use ty;
use util::nodemap::NodeMap;
use util::nodemap::{NodeMap, ItemLocalMap};
use std::hash as std_hash;
use std::collections::{HashMap, HashSet, BTreeMap};
@ -358,6 +358,18 @@ pub fn hash_stable_nodemap<'a, 'tcx, 'gcx, V, W>(
});
}
pub fn hash_stable_itemlocalmap<'a, 'tcx, 'gcx, V, W>(
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>,
map: &ItemLocalMap<V>)
where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
W: StableHasherResult,
{
hash_stable_hashmap(hcx, hasher, map, |_, local_id| {
*local_id
});
}
pub fn hash_stable_btreemap<'a, 'tcx, 'gcx, K, V, SK, F, W>(
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,

View File

@ -506,6 +506,7 @@ impl_stable_hash_for!(struct hir::Local {
ty,
init,
id,
hir_id,
span,
attrs,
source

View File

@ -638,12 +638,10 @@ for ty::TypeckTables<'gcx> {
} = *self;
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
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);
ich::hash_stable_itemlocalmap(hcx, hasher, type_dependent_defs);
ich::hash_stable_itemlocalmap(hcx, hasher, node_types);
ich::hash_stable_itemlocalmap(hcx, hasher, node_substs);
ich::hash_stable_itemlocalmap(hcx, hasher, adjustments);
ich::hash_stable_nodemap(hcx, hasher, pat_binding_modes);
ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
let ty::UpvarId {

View File

@ -14,7 +14,7 @@ pub use self::fingerprint::Fingerprint;
pub use self::caching_codemap_view::CachingCodemapView;
pub use self::hcx::{StableHashingContext, NodeIdHashingMode, hash_stable_hashmap,
hash_stable_hashset, hash_stable_nodemap,
hash_stable_btreemap};
hash_stable_btreemap, hash_stable_itemlocalmap};
mod fingerprint;
mod caching_codemap_view;
mod hcx;

View File

@ -8,13 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use hir::{self, Local, Pat, Body};
use hir::{self, Local, Pat, Body, HirId};
use hir::intravisit::{self, Visitor, NestedVisitorMap};
use infer::InferCtxt;
use infer::type_variable::TypeVariableOrigin;
use ty::{self, Ty, TyInfer, TyVar};
use syntax::ast::NodeId;
use syntax_pos::Span;
struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
@ -26,7 +24,7 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
}
impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
fn node_matches_type(&mut self, node_id: NodeId) -> bool {
fn node_matches_type(&mut self, node_id: HirId) -> bool {
let ty_opt = self.infcx.in_progress_tables.and_then(|tables| {
tables.borrow().node_id_to_type_opt(node_id)
});
@ -56,7 +54,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
}
fn visit_local(&mut self, local: &'gcx Local) {
if self.found_local_pattern.is_none() && self.node_matches_type(local.id) {
if self.found_local_pattern.is_none() && self.node_matches_type(local.hir_id) {
self.found_local_pattern = Some(&*local.pat);
}
intravisit::walk_local(self, local);
@ -64,7 +62,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
fn visit_body(&mut self, body: &'gcx Body) {
for argument in &body.arguments {
if self.found_arg_pattern.is_none() && self.node_matches_type(argument.id) {
if self.found_arg_pattern.is_none() && self.node_matches_type(argument.hir_id) {
self.found_arg_pattern = Some(&*argument.pat);
}
}

View File

@ -46,7 +46,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.iter()
.enumerate()
.filter_map(|(index, arg)| {
let ty = tables.borrow().node_id_to_type(arg.id);
let ty = tables.borrow().node_id_to_type(arg.hir_id);
let mut found_anon_region = false;
let new_arg_ty = self.tcx
.fold_regions(&ty, &mut false, |r, _| if *r == *anon_region {

View File

@ -121,7 +121,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
pats: &[codemap::Spanned<hir::FieldPat>]) {
let variant = match self.tables.node_id_to_type(lhs.id).sty {
let variant = match self.tables.node_id_to_type(lhs.hir_id).sty {
ty::TyAdt(adt, _) => adt.variant_of_def(def),
_ => span_bug!(lhs.span, "non-ADT in struct pattern")
};

View File

@ -296,7 +296,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
debug!("consume_body(body={:?})", body);
for arg in &body.arguments {
let arg_ty = return_if_err!(self.mc.node_ty(arg.pat.id));
let arg_ty = return_if_err!(self.mc.node_ty(arg.pat.hir_id));
let fn_body_scope_r = self.tcx().node_scope_region(body.value.id);
let arg_cmt = self.mc.cat_rvalue(
@ -826,7 +826,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
let bm = *mc.tables.pat_binding_modes.get(&pat.id).expect("missing binding mode");
// pat_ty: the type of the binding being produced.
let pat_ty = return_if_err!(mc.node_ty(pat.id));
let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
// Each match binding is effectively an assignment to the
// binding being produced.
@ -923,8 +923,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
-> mc::McResult<mc::cmt<'tcx>> {
// Create the cmt for the variable being borrowed, from the
// caller's perspective
let var_id = self.tcx().hir.as_local_node_id(upvar_def.def_id()).unwrap();
let var_ty = self.mc.node_ty(var_id)?;
let var_node_id = self.tcx().hir.as_local_node_id(upvar_def.def_id()).unwrap();
let var_hir_id = self.tcx().hir.node_to_hir_id(var_node_id);
let var_ty = self.mc.node_ty(var_hir_id)?;
self.mc.cat_def(closure_id, closure_span, var_ty, upvar_def)
}
}

View File

@ -152,7 +152,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
};
if let Def::Fn(did) = def {
if self.def_id_is_transmute(did) {
let typ = self.tables.node_id_to_type(expr.id);
let typ = self.tables.node_id_to_type(expr.hir_id);
let sig = typ.fn_sig(self.tcx);
let from = sig.inputs().skip_binder()[0];
let to = *sig.output().skip_binder();

View File

@ -435,7 +435,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
}
fn resolve_type_vars_or_error(&self,
id: ast::NodeId,
id: hir::HirId,
ty: Option<Ty<'tcx>>)
-> McResult<Ty<'tcx>> {
match ty {
@ -451,26 +451,30 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
// FIXME
None if self.is_tainted_by_errors() => Err(()),
None => {
let id = self.tcx.hir.definitions().find_node_for_hir_id(id);
bug!("no type for node {}: {} in mem_categorization",
id, self.tcx.hir.node_to_string(id));
}
}
}
pub fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
self.resolve_type_vars_or_error(id, self.tables.node_id_to_type_opt(id))
pub fn node_ty(&self,
hir_id: hir::HirId)
-> McResult<Ty<'tcx>> {
self.resolve_type_vars_or_error(hir_id,
self.tables.node_id_to_type_opt(hir_id))
}
pub fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
self.resolve_type_vars_or_error(expr.id, self.tables.expr_ty_opt(expr))
self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_opt(expr))
}
pub fn expr_ty_adjusted(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
self.resolve_type_vars_or_error(expr.id, self.tables.expr_ty_adjusted_opt(expr))
self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_adjusted_opt(expr))
}
fn pat_ty(&self, pat: &hir::Pat) -> McResult<Ty<'tcx>> {
let base_ty = self.node_ty(pat.id)?;
let base_ty = self.node_ty(pat.hir_id)?;
// FIXME (Issue #18207): This code detects whether we are
// looking at a `ref x`, and if so, figures out what the type
// *being borrowed* is. But ideally we would put in a more
@ -714,7 +718,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
let upvar_id = ty::UpvarId { var_id,
closure_expr_id: fn_node_id };
let var_ty = self.node_ty(var_id)?;
let var_hir_id = self.tcx.hir.node_to_hir_id(var_id);
let var_ty = self.node_ty(var_hir_id)?;
// Mutability of original variable itself
let var_mutbl = MutabilityCategory::from_local(self.tcx, self.tables, var_id);

View File

@ -57,7 +57,7 @@ use std::ops::Deref;
use std::iter;
use std::rc::Rc;
use syntax::abi;
use syntax::ast::{self, Name, NodeId};
use syntax::ast::{self, Name};
use syntax::attr;
use syntax::codemap::MultiSpan;
use syntax::symbol::{Symbol, keywords};
@ -219,15 +219,15 @@ pub struct TypeckTables<'tcx> {
/// Stores the types for various nodes in the AST. Note that this table
/// is not guaranteed to be populated until after typeck. See
/// typeck::check::fn_ctxt for details.
pub node_types: NodeMap<Ty<'tcx>>,
pub node_types: ItemLocalMap<Ty<'tcx>>,
/// Stores the type parameters which were substituted to obtain the type
/// of this node. This only applies to nodes that refer to entities
/// parameterized by type parameters, such as generic fns, types, or
/// other items.
pub node_substs: NodeMap<&'tcx Substs<'tcx>>,
pub node_substs: ItemLocalMap<&'tcx Substs<'tcx>>,
pub adjustments: NodeMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
// Stores the actual binding mode for all instances of hir::BindingAnnotation.
pub pat_binding_modes: NodeMap<BindingMode>,
@ -278,9 +278,9 @@ impl<'tcx> TypeckTables<'tcx> {
TypeckTables {
local_id_root,
type_dependent_defs: ItemLocalMap(),
node_types: FxHashMap(),
node_substs: NodeMap(),
adjustments: NodeMap(),
node_types: ItemLocalMap(),
node_substs: ItemLocalMap(),
adjustments: ItemLocalMap(),
pat_binding_modes: NodeMap(),
upvar_capture_map: FxHashMap(),
closure_tys: NodeMap(),
@ -305,32 +305,37 @@ impl<'tcx> TypeckTables<'tcx> {
}
}
pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> {
pub fn node_id_to_type(&self, id: hir::HirId) -> Ty<'tcx> {
match self.node_id_to_type_opt(id) {
Some(ty) => ty,
None => {
bug!("node_id_to_type: no type for node `{}`",
tls::with(|tcx| tcx.hir.node_to_string(id)))
tls::with(|tcx| {
let id = tcx.hir.definitions().find_node_for_hir_id(id);
tcx.hir.node_to_string(id)
}))
}
}
}
pub fn node_id_to_type_opt(&self, id: NodeId) -> Option<Ty<'tcx>> {
self.node_types.get(&id).cloned()
pub fn node_id_to_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
self.validate_hir_id(id);
self.node_types.get(&id.local_id).cloned()
}
pub fn node_substs(&self, id: NodeId) -> &'tcx Substs<'tcx> {
self.node_substs.get(&id).cloned().unwrap_or(Substs::empty())
pub fn node_substs(&self, id: hir::HirId) -> &'tcx Substs<'tcx> {
self.validate_hir_id(id);
self.node_substs.get(&id.local_id).cloned().unwrap_or(Substs::empty())
}
// Returns the type of a pattern as a monotype. Like @expr_ty, this function
// doesn't provide type parameter substitutions.
pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
self.node_id_to_type(pat.id)
self.node_id_to_type(pat.hir_id)
}
pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
self.node_id_to_type_opt(pat.id)
self.node_id_to_type_opt(pat.hir_id)
}
// Returns the type of an expression as a monotype.
@ -344,16 +349,17 @@ impl<'tcx> TypeckTables<'tcx> {
// ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
// instead of "fn(ty) -> T with T = isize".
pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
self.node_id_to_type(expr.id)
self.node_id_to_type(expr.hir_id)
}
pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
self.node_id_to_type_opt(expr.id)
self.node_id_to_type_opt(expr.hir_id)
}
pub fn expr_adjustments(&self, expr: &hir::Expr)
-> &[ty::adjustment::Adjustment<'tcx>] {
self.adjustments.get(&expr.id).map_or(&[], |a| &a[..])
self.validate_hir_id(expr.hir_id);
self.adjustments.get(&expr.hir_id.local_id).map_or(&[], |a| &a[..])
}
/// Returns the type of `expr`, considering any `Adjustment`

View File

@ -155,7 +155,9 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
}
fn decl_without_init(&mut self, id: ast::NodeId, _span: Span) {
let ty = self.bccx.tables.node_id_to_type(id);
let ty = self.bccx
.tables
.node_id_to_type(self.bccx.tcx.hir.node_to_hir_id(id));
gather_moves::gather_decl(self.bccx, &self.move_data, id, ty);
}
}

View File

@ -188,7 +188,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
// Then, if the match has no arms, check whether the scrutinee
// is uninhabited.
let pat_ty = self.tables.node_id_to_type(scrut.id);
let pat_ty = self.tables.node_id_to_type(scrut.hir_id);
let module = self.tcx.hir.get_module_parent(scrut.id);
if inlined_arms.is_empty() {
let scrutinee_is_uninhabited = if self.tcx.sess.features.borrow().never_type {
@ -217,7 +217,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
.flat_map(|arm| &arm.0)
.map(|pat| vec![pat.0])
.collect();
let scrut_ty = self.tables.node_id_to_type(scrut.id);
let scrut_ty = self.tables.node_id_to_type(scrut.hir_id);
check_exhaustive(cx, scrut_ty, scrut.span, &matrix);
})
}
@ -494,7 +494,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor,
let bm = *cx.tables.pat_binding_modes.get(&p.id).expect("missing binding mode");
match bm {
ty::BindByValue(..) => {
let pat_ty = cx.tables.node_id_to_type(p.id);
let pat_ty = cx.tables.node_id_to_type(p.hir_id);
if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) {
check_move(p, sub.as_ref().map(|p| &**p));
}

View File

@ -275,7 +275,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);
let substs = cx.tables.node_substs(e.hir_id).subst(tcx, cx.substs);
match cx.tables.qpath_def(qpath, e.hir_id) {
Def::Const(def_id) |
Def::AssociatedConst(def_id) => {

View File

@ -303,7 +303,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
pub fn lower_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
let mut ty = self.tables.node_id_to_type(pat.id);
let mut ty = self.tables.node_id_to_type(pat.hir_id);
let kind = match pat.node {
PatKind::Wild => PatternKind::Wild,
@ -321,7 +321,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
PatKind::Path(ref qpath) => {
return self.lower_path(qpath, (pat.id, pat.hir_id), pat.id, pat.span);
return self.lower_path(qpath, pat.hir_id, pat.id, pat.span);
}
PatKind::Ref(ref subpattern, _) |
@ -330,7 +330,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
PatKind::Slice(ref prefix, ref slice, ref suffix) => {
let ty = self.tables.node_id_to_type(pat.id);
let ty = self.tables.node_id_to_type(pat.hir_id);
match ty.sty {
ty::TyRef(_, mt) =>
PatternKind::Deref {
@ -355,7 +355,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
PatKind::Tuple(ref subpatterns, ddpos) => {
let ty = self.tables.node_id_to_type(pat.id);
let ty = self.tables.node_id_to_type(pat.hir_id);
match ty.sty {
ty::TyTuple(ref tys, _) => {
let subpatterns =
@ -376,7 +376,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
PatKind::Binding(_, def_id, ref ident, ref sub) => {
let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
let var_ty = self.tables.node_id_to_type(pat.id);
let var_ty = self.tables.node_id_to_type(pat.hir_id);
let region = match var_ty.sty {
ty::TyRef(r, _) => Some(r),
_ => None,
@ -590,12 +590,12 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
fn lower_path(&mut self,
qpath: &hir::QPath,
(id, hir_id): (ast::NodeId, hir::HirId),
id: 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, hir_id);
let def = self.tables.qpath_def(qpath, id);
let kind = match def {
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
let substs = self.tables.node_substs(id);
@ -695,7 +695,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
hir::ExprPath(ref qpath) => qpath,
_ => bug!()
};
let ty = self.tables.node_id_to_type(callee.id);
let ty = self.tables.node_id_to_type(callee.hir_id);
let def = self.tables.qpath_def(qpath, callee.hir_id);
match def {
Def::Fn(..) | Def::Method(..) => self.lower_lit(expr),
@ -755,7 +755,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
}
hir::ExprPath(ref qpath) => {
return self.lower_path(qpath, (expr.id, expr.hir_id), pat_id, span);
return self.lower_path(qpath, expr.hir_id, pat_id, span);
}
_ => self.lower_lit(expr)

View File

@ -139,7 +139,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers {
}
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
let ty = cx.tables.node_id_to_type(e.id);
let ty = cx.tables.node_id_to_type(e.hir_id);
self.check_heap_type(cx, e.span, ty);
}
}
@ -934,9 +934,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
// Check for method calls and overloaded operators.
if cx.tables.is_method_call(expr) {
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);
let hir_id = cx.tcx.hir.definitions().node_to_hir_id(id);
let def_id = cx.tables.type_dependent_defs[&hir_id.local_id].def_id();
let substs = cx.tables.node_substs(hir_id);
if method_call_refers_to_method(cx, method, def_id, substs, id) {
return true;
}
@ -952,7 +952,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
};
match def {
Def::Method(def_id) => {
let substs = cx.tables.node_substs(callee.id);
let substs = cx.tables.node_substs(callee.hir_id);
method_call_refers_to_method(cx, method, def_id, substs, id)
}
_ => false,
@ -1188,7 +1188,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
if !def_id_is_transmute(cx, did) {
return None;
}
let sig = cx.tables.node_id_to_type(expr.id).fn_sig(cx.tcx);
let sig = cx.tables.node_id_to_type(expr.hir_id).fn_sig(cx.tcx);
let from = sig.inputs().skip_binder()[0];
let to = *sig.output().skip_binder();
return Some((&from.sty, &to.sty));

View File

@ -92,7 +92,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
}
if binop.node.is_shift() {
let opt_ty_bits = match cx.tables.node_id_to_type(l.id).sty {
let opt_ty_bits = match cx.tables.node_id_to_type(l.hir_id).sty {
ty::TyInt(t) => Some(int_ty_bits(t, cx.sess().target.int_type)),
ty::TyUint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)),
_ => None,
@ -135,7 +135,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
}
}
hir::ExprLit(ref lit) => {
match cx.tables.node_id_to_type(e.id).sty {
match cx.tables.node_id_to_type(e.hir_id).sty {
ty::TyInt(t) => {
match lit.node {
ast::LitKind::Int(v, ast::LitIntType::Signed(_)) |
@ -285,7 +285,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
// Normalize the binop so that the literal is always on the RHS in
// the comparison
let norm_binop = if swap { rev_binop(binop) } else { binop };
match cx.tables.node_id_to_type(expr.id).sty {
match cx.tables.node_id_to_type(expr.hir_id).sty {
ty::TyInt(int_ty) => {
let (min, max) = int_ty_range(int_ty);
let lit_val: i128 = match lit.node {

View File

@ -202,7 +202,8 @@ fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
closure_expr_id: ast::NodeId,
body_id: hir::BodyId)
-> Ty<'tcx> {
let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id);
let closure_expr_hir_id = tcx.hir.node_to_hir_id(closure_expr_id);
let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_hir_id);
let closure_def_id = tcx.hir.local_def_id(closure_expr_id);
let region = ty::ReFree(ty::FreeRegion {

View File

@ -95,7 +95,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
block: &'tcx hir::Block)
-> ExprRef<'tcx> {
let block_ty = cx.tables().node_id_to_type(block.id);
let block_ty = cx.tables().node_id_to_type(block.hir_id);
let temp_lifetime = cx.region_maps.temporary_scope(block.id);
let expr = Expr {
ty: block_ty,

View File

@ -217,7 +217,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
None
};
if let Some((adt_def, index)) = adt_data {
let substs = cx.tables().node_substs(fun.id);
let substs = cx.tables().node_substs(fun.hir_id);
let field_refs = args.iter()
.enumerate()
.map(|(idx, e)| {
@ -236,7 +236,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
}
} else {
ExprKind::Call {
ty: cx.tables().node_id_to_type(fun.id),
ty: cx.tables().node_id_to_type(fun.hir_id),
fun: fun.to_ref(),
args: args.to_ref(),
}
@ -582,7 +582,7 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let (def_id, substs) = custom_callee.unwrap_or_else(|| {
cx.tables().validate_hir_id(expr.hir_id);
(cx.tables().type_dependent_defs[&expr.hir_id.local_id].def_id(),
cx.tables().node_substs(expr.id))
cx.tables().node_substs(expr.hir_id))
});
Expr {
temp_lifetime: temp_lifetime,
@ -620,7 +620,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
expr: &'tcx hir::Expr,
def: Def)
-> ExprKind<'tcx> {
let substs = cx.tables().node_substs(expr.id);
let substs = cx.tables().node_substs(expr.hir_id);
match def {
// A regular function, constructor function or a constant.
Def::Fn(def_id) |
@ -642,7 +642,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
Def::StructCtor(def_id, CtorKind::Const) |
Def::VariantCtor(def_id, CtorKind::Const) => {
match cx.tables().node_id_to_type(expr.id).sty {
match cx.tables().node_id_to_type(expr.hir_id).sty {
// A unit struct/variant which is used as a value.
// We return a completely different ExprKind here to account for this special case.
ty::TyAdt(adt_def, substs) => {
@ -684,10 +684,12 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
id_var,
index,
closure_expr_id);
let var_ty = cx.tables().node_id_to_type(id_var);
let var_ty = cx.tables()
.node_id_to_type(cx.tcx.hir.node_to_hir_id(id_var));
// FIXME free regions in closures are not right
let closure_ty = cx.tables().node_id_to_type(closure_expr_id);
let closure_ty = cx.tables()
.node_id_to_type(cx.tcx.hir.node_to_hir_id(closure_expr_id));
// FIXME we're just hard-coding the idea that the
// signature will be &self or &mut self and hence will
@ -879,7 +881,8 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
};
let upvar_capture = cx.tables().upvar_capture(upvar_id);
let temp_lifetime = cx.region_maps.temporary_scope(closure_expr.id);
let var_ty = cx.tables().node_id_to_type(id_var);
let var_ty = cx.tables()
.node_id_to_type(cx.tcx.hir.node_to_hir_id(id_var));
let captured_var = Expr {
temp_lifetime: temp_lifetime,
ty: var_ty,

View File

@ -219,7 +219,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
let outer = self.promotable;
self.promotable = true;
let node_ty = self.tables.node_id_to_type(ex.id);
let node_ty = self.tables.node_id_to_type(ex.hir_id);
check_expr(self, ex, node_ty);
check_adjustments(self, ex);
@ -297,7 +297,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
v.promotable = false;
}
hir::ExprUnary(op, ref inner) => {
match v.tables.node_id_to_type(inner.id).sty {
match v.tables.node_id_to_type(inner.hir_id).sty {
ty::TyRawPtr(_) => {
assert!(op == hir::UnDeref);
@ -307,7 +307,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
}
}
hir::ExprBinary(op, ref lhs, _) => {
match v.tables.node_id_to_type(lhs.id).sty {
match v.tables.node_id_to_type(lhs.hir_id).sty {
ty::TyRawPtr(_) => {
assert!(op.node == hir::BiEq || op.node == hir::BiNe ||
op.node == hir::BiLe || op.node == hir::BiLt ||

View File

@ -639,7 +639,7 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
}
// Take node ID of an expression or pattern and check its type for privacy.
fn check_expr_pat_type(&mut self, id: ast::NodeId, span: Span) -> bool {
fn check_expr_pat_type(&mut self, id: hir::HirId, span: Span) -> bool {
self.span = span;
if let Some(ty) = self.tables.node_id_to_type_opt(id) {
if ty.visit_with(self) {
@ -649,7 +649,7 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
if self.tables.node_substs(id).visit_with(self) {
return true;
}
if let Some(adjustments) = self.tables.adjustments.get(&id) {
if let Some(adjustments) = self.tables.adjustments.get(&id.local_id) {
for adjustment in adjustments {
if adjustment.target.visit_with(self) {
return true;
@ -735,14 +735,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
// Check types of expressions
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
if self.check_expr_pat_type(expr.id, expr.span) {
if self.check_expr_pat_type(expr.hir_id, expr.span) {
// Do not check nested expressions if the error already happened.
return;
}
match expr.node {
hir::ExprAssign(.., ref rhs) | hir::ExprMatch(ref rhs, ..) => {
// Do not report duplicate errors for `x = y` and `match x { ... }`.
if self.check_expr_pat_type(rhs.id, rhs.span) {
if self.check_expr_pat_type(rhs.hir_id, rhs.span) {
return;
}
}
@ -783,7 +783,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
// Check types of patterns
fn visit_pat(&mut self, pattern: &'tcx hir::Pat) {
if self.check_expr_pat_type(pattern.id, pattern.span) {
if self.check_expr_pat_type(pattern.hir_id, pattern.span) {
// Do not check nested patterns if the error already happened.
return;
}
@ -793,7 +793,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
fn visit_local(&mut self, local: &'tcx hir::Local) {
if let Some(ref init) = local.init {
if self.check_expr_pat_type(init.id, init.span) {
if self.check_expr_pat_type(init.hir_id, init.span) {
// Do not report duplicate errors for `let x = y`.
return;
}

View File

@ -345,7 +345,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
collector.visit_pat(&arg.pat);
let span_utils = self.span.clone();
for &(id, ref p, ..) in &collector.collected_paths {
let typ = match self.save_ctxt.tables.node_types.get(&id) {
let hir_id = self.tcx.hir.node_to_hir_id(id);
let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) {
Some(s) => s.to_string(),
None => continue,
};
@ -893,7 +894,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
match p.node {
PatKind::Struct(ref _path, ref fields, _) => {
// FIXME do something with _path?
let adt = match self.save_ctxt.tables.node_id_to_type_opt(p.id) {
let hir_id = self.tcx.hir.node_to_hir_id(p.id);
let adt = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) {
Some(ty) => ty.ty_adt_def().unwrap(),
None => {
visit::walk_pat(self, p);
@ -935,7 +937,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
ast::Mutability::Immutable => value.to_string(),
_ => String::new(),
};
let typ = match self.save_ctxt.tables.node_types.get(&id) {
let hir_id = self.tcx.hir.node_to_hir_id(id);
let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) {
Some(typ) => {
let typ = typ.to_string();
if !value.is_empty() {
@ -1466,8 +1469,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
} else {
"<mutable>".to_string()
};
let typ = self.save_ctxt.tables.node_types
.get(&id).map(|t| t.to_string()).unwrap_or(String::new());
let hir_id = self.tcx.hir.node_to_hir_id(id);
let typ = self.save_ctxt
.tables
.node_id_to_type_opt(hir_id)
.map(|t| t.to_string())
.unwrap_or(String::new());
value.push_str(": ");
value.push_str(&typ);

View File

@ -323,7 +323,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
};
self.write_ty(pat.id, ty);
self.write_ty(pat.hir_id, ty);
// (*) In most of the cases above (literals and constants being
// the exception), we relate types using strict equality, evewn

View File

@ -314,7 +314,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
TupleArgumentsFlag::TupleArguments,
expected);
self.write_method_call((call_expr.id, call_expr.hir_id), method_callee);
self.write_method_call(call_expr.hir_id, method_callee);
output_type
}
}
@ -364,7 +364,7 @@ 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, self.call_expr.hir_id),
fcx.write_method_call(self.call_expr.hir_id,
method_callee);
}
None => {

View File

@ -844,7 +844,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// First try to coerce the new expression to the type of the previous ones,
// but only if the new expression has no coercion already applied to it.
let mut first_error = None;
if !self.tables.borrow().adjustments.contains_key(&new.id) {
if !self.tables.borrow().adjustments.contains_key(&new.hir_id.local_id) {
let result = self.commit_if_ok(|_| coerce.coerce(new_ty, prev_ty));
match result {
Ok(ok) => {
@ -866,7 +866,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Adjustment { kind: Adjust::Deref(_), .. },
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl_adj)), .. }
] => {
match self.node_ty(expr.id).sty {
match self.node_ty(expr.hir_id).sty {
ty::TyRef(_, mt_orig) => {
// Reborrow that we can safely ignore, because
// the next adjustment can only be a Deref

View File

@ -445,11 +445,14 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
// Fix up the autoderefs. Autorefs can only occur immediately preceding
// overloaded lvalue ops, and will be fixed by them in order to get
// the correct region.
let mut source = self.node_ty(expr.id);
let mut source = self.node_ty(expr.hir_id);
// Do not mutate adjustments in place, but rather take them,
// and replace them after mutating them, to avoid having the
// tables borrowed during (`deref_mut`) method resolution.
let previous_adjustments = self.tables.borrow_mut().adjustments.remove(&expr.id);
let previous_adjustments = self.tables
.borrow_mut()
.adjustments
.remove(&expr.hir_id.local_id);
if let Some(mut adjustments) = previous_adjustments {
let pref = LvaluePreference::PreferMutLvalue;
for adjustment in &mut adjustments {
@ -466,12 +469,12 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
}
source = adjustment.target;
}
self.tables.borrow_mut().adjustments.insert(expr.id, adjustments);
self.tables.borrow_mut().adjustments.insert(expr.hir_id.local_id, adjustments);
}
match expr.node {
hir::ExprIndex(ref base_expr, ref index_expr) => {
let index_expr_ty = self.node_ty(index_expr.id);
let index_expr_ty = self.node_ty(index_expr.hir_id);
self.convert_lvalue_op_to_mutable(
LvalueOp::Index, expr, base_expr, &[index_expr_ty]);
}
@ -498,7 +501,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
}
let base_ty = self.tables.borrow().expr_adjustments(base_expr).last()
.map_or_else(|| self.node_ty(expr.id), |adj| adj.target);
.map_or_else(|| self.node_ty(expr.hir_id), |adj| adj.target);
let base_ty = self.resolve_type_vars_if_possible(&base_ty);
// Need to deref because overloaded lvalue ops take self by-reference.
@ -513,7 +516,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, expr.hir_id), method);
self.write_method_call(expr.hir_id, method);
let (region, mutbl) = if let ty::TyRef(r, mt) = method.sig.inputs()[0].sty {
(r, mt.mutbl)
@ -523,8 +526,11 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
// Convert the autoref in the base expr to mutable with the correct
// region and mutability.
let base_expr_ty = self.node_ty(base_expr.id);
if let Some(adjustments) = self.tables.borrow_mut().adjustments.get_mut(&base_expr.id) {
let base_expr_ty = self.node_ty(base_expr.hir_id);
if let Some(adjustments) = self.tables
.borrow_mut()
.adjustments
.get_mut(&base_expr.hir_id.local_id) {
let mut source = base_expr_ty;
for adjustment in &mut adjustments[..] {
if let Adjust::Borrow(AutoBorrow::Ref(..)) = adjustment.kind {

View File

@ -1024,7 +1024,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::MiscObligation);
}
fcx.write_ty(arg.id, arg_ty);
fcx.write_ty(arg.hir_id, arg_ty);
}
inherited.tables.borrow_mut().liberated_fn_sigs.insert(fn_id, fn_sig);
@ -1807,10 +1807,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
#[inline]
pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
debug!("write_ty({}, {:?}) in fcx {}",
node_id, self.resolve_type_vars_if_possible(&ty), self.tag());
self.tables.borrow_mut().node_types.insert(node_id, ty);
pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
debug!("write_ty({:?}, {:?}) in fcx {}",
id, self.resolve_type_vars_if_possible(&ty), self.tag());
{
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(id);
tables.node_types.insert(id.local_id, ty);
}
if ty.references_error() {
self.has_errors.set(true);
@ -1821,24 +1825,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// 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),
hir_id: hir::HirId,
method: MethodCallee<'tcx>) {
{
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(hir_id);
tables.type_dependent_defs.insert(hir_id.local_id, Def::Method(method.def_id));
}
self.write_substs(node_id, method.substs);
self.write_substs(hir_id, method.substs);
}
pub fn write_substs(&self, node_id: ast::NodeId, substs: &'tcx Substs<'tcx>) {
pub fn write_substs(&self, node_id: hir::HirId, substs: &'tcx Substs<'tcx>) {
if !substs.is_noop() {
debug!("write_substs({}, {:?}) in fcx {}",
debug!("write_substs({:?}, {:?}) in fcx {}",
node_id,
substs,
self.tag());
self.tables.borrow_mut().node_substs.insert(node_id, substs);
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(node_id);
tables.node_substs.insert(node_id.local_id, substs);
}
}
@ -1849,7 +1855,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
return;
}
match self.tables.borrow_mut().adjustments.entry(expr.id) {
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(expr.hir_id);
match tables.adjustments.entry(expr.hir_id.local_id) {
Entry::Vacant(entry) => { entry.insert(adj); },
Entry::Occupied(mut entry) => {
debug!(" - composing on top of {:?}", entry.get());
@ -2002,13 +2010,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
t
}
pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
match self.tables.borrow().node_types.get(&id) {
pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
let tables = self.tables.borrow();
tables.validate_hir_id(id);
match tables.node_types.get(&id.local_id) {
Some(&t) => t,
None if self.err_count_since_creation() != 0 => self.tcx.types.err,
None => {
let node_id = self.tcx.hir.definitions().find_node_for_hir_id(id);
bug!("no type for node {}: {} in fcx {}",
id, self.tcx.hir.node_to_string(id),
node_id, self.tcx.hir.node_to_string(node_id),
self.tag());
}
}
@ -2276,7 +2287,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
self.apply_adjustments(base_expr, adjustments);
self.write_method_call((expr.id, expr.hir_id), method);
self.write_method_call(expr.hir_id, method);
(input_ty, self.make_overloaded_lvalue_return_type(method).ty)
});
if result.is_some() {
@ -2665,7 +2676,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// While we don't allow *arbitrary* coercions here, we *do* allow
// coercions from ! to `expected`.
if ty.is_never() {
assert!(!self.tables.borrow().adjustments.contains_key(&expr.id),
assert!(!self.tables.borrow().adjustments.contains_key(&expr.hir_id.local_id),
"expression with never type wound up being adjusted");
let adj_ty = self.next_diverging_ty_var(
TypeVariableOrigin::AdjustmentType(expr.span));
@ -2816,7 +2827,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
expr,
rcvr) {
Ok(method) => {
self.write_method_call((expr.id, expr.hir_id), method);
self.write_method_call(expr.hir_id, method);
Ok(method)
}
Err(error) => {
@ -3448,7 +3459,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Record the type, which applies it effects.
// We need to do this after the warning above, so that
// we don't warn for the diverging expression itself.
self.write_ty(expr.id, ty);
self.write_ty(expr.hir_id, ty);
// Combine the diverging and has_error flags.
self.diverges.set(self.diverges.get() | old_diverges);
@ -3521,7 +3532,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, expr.hir_id), method);
self.write_method_call(expr.hir_id, method);
} else {
type_error_struct!(tcx.sess, expr.span, oprnd_t, E0614,
"type `{}` cannot be dereferenced",
@ -3599,7 +3610,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// We always require that the type provided as the value for
// a type parameter outlives the moment of instantiation.
let substs = self.tables.borrow().node_substs(expr.id);
let substs = self.tables.borrow().node_substs(expr.hir_id);
self.add_wf_bounds(substs, expr);
ty
@ -4101,19 +4112,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn check_decl_local(&self, local: &'gcx hir::Local) {
let t = self.local_ty(local.span, local.id);
self.write_ty(local.id, t);
self.write_ty(local.hir_id, t);
if let Some(ref init) = local.init {
let init_ty = self.check_decl_initializer(local, &init);
if init_ty.references_error() {
self.write_ty(local.id, init_ty);
self.write_ty(local.hir_id, init_ty);
}
}
self.check_pat(&local.pat, t);
let pat_ty = self.node_ty(local.pat.id);
let pat_ty = self.node_ty(local.pat.hir_id);
if pat_ty.references_error() {
self.write_ty(local.id, pat_ty);
self.write_ty(local.hir_id, pat_ty);
}
}
@ -4265,7 +4276,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ty = self.tcx.types.err
}
self.write_ty(blk.id, ty);
self.write_ty(blk.hir_id, ty);
*self.ps.borrow_mut() = prev;
ty
@ -4443,7 +4454,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
hir::StmtSemi(ref e, _) => e,
_ => return,
};
let last_expr_ty = self.node_ty(last_expr.id);
let last_expr_ty = self.node_ty(last_expr.hir_id);
if self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err() {
return;
}
@ -4586,7 +4597,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let nid = self.tcx.hir.as_local_node_id(def_id).unwrap();
let ty = self.local_ty(span, nid);
let ty = self.normalize_associated_types_in(span, &ty);
self.write_ty(node_id, ty);
self.write_ty(self.tcx.hir.node_to_hir_id(node_id), ty);
return ty;
}
_ => {}
@ -4718,7 +4729,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
debug!("instantiate_value_path: type of {:?} is {:?}",
node_id,
ty_substituted);
self.write_substs(node_id, substs);
self.write_substs(self.tcx.hir.node_to_hir_id(node_id), substs);
ty_substituted
}

View File

@ -210,11 +210,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// some cases applied on the RHS, on top of which we need
// to autoref, which is not allowed by apply_adjustments.
// self.apply_adjustments(rhs_expr, vec![autoref]);
self.tables.borrow_mut().adjustments.entry(rhs_expr.id)
let mut tables = self.tables.borrow_mut();
tables.validate_hir_id(rhs_expr.hir_id);
tables.adjustments.entry(rhs_expr.hir_id.local_id)
.or_insert(vec![]).push(autoref);
}
}
self.write_method_call((expr.id, expr.hir_id), method);
self.write_method_call(expr.hir_id, method);
method.sig.output()
}
@ -340,7 +342,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, ex.hir_id), method);
self.write_method_call(ex.hir_id, method);
method.sig.output()
}
Err(()) => {

View File

@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
}
/// Try to resolve the type for the given node.
fn resolve_node_type(&self, id: ast::NodeId) -> Ty<'tcx> {
fn resolve_node_type(&self, id: hir::HirId) -> Ty<'tcx> {
let t = self.node_ty(id);
self.resolve_type(t)
}
@ -338,8 +338,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
debug!("visit_fn_body body.id {:?} call_site_scope: {:?}",
body.id(), call_site_scope);
let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope));
let body_hir_id = self.tcx.hir.node_to_hir_id(body_id.node_id);
self.type_of_node_must_outlive(infer::CallReturn(span),
body_id.node_id,
body_hir_id,
call_site_region);
self.region_bound_pairs.truncate(old_region_bounds_pairs_len);
@ -613,9 +614,10 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
let var_region = self.tcx.mk_region(ty::ReScope(var_scope));
let origin = infer::BindingTypeIsNotValidAtDecl(span);
self.type_of_node_must_outlive(origin, id, var_region);
let hir_id = self.tcx.hir.node_to_hir_id(id);
self.type_of_node_must_outlive(origin, hir_id, var_region);
let typ = self.resolve_node_type(id);
let typ = self.resolve_node_type(hir_id);
let _ = dropck::check_safety_of_destructor_if_necessary(
self, typ, span, var_scope);
})
@ -664,7 +666,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
// No matter what, the type of each expression must outlive the
// scope of that expression. This also guarantees basic WF.
let expr_ty = self.resolve_node_type(expr.id);
let expr_ty = self.resolve_node_type(expr.hir_id);
// the region corresponding to this expression
let expr_region = self.tcx.node_scope_region(expr.id);
self.type_must_outlive(infer::ExprTypeIsNotInScope(expr_ty, expr.span),
@ -686,7 +688,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
infer::ParameterOrigin::OverloadedOperator
};
let substs = self.tables.borrow().node_substs(expr.id);
let substs = self.tables.borrow().node_substs(expr.hir_id);
self.substs_wf_in_scope(origin, substs, expr.span, expr_region);
// Arguments (sub-expressions) are checked via `constrain_call`, below.
}
@ -709,7 +711,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
expr, self.repeating_scope);
match expr.node {
hir::ExprPath(_) => {
let substs = self.tables.borrow().node_substs(expr.id);
let substs = self.tables.borrow().node_substs(expr.hir_id);
let origin = infer::ParameterOrigin::Path;
self.substs_wf_in_scope(origin, substs, expr.span, expr_region);
}
@ -718,7 +720,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
if is_method_call {
self.constrain_call(expr, Some(&callee), args.iter().map(|e| &*e));
} else {
self.constrain_callee(callee.id, expr, &callee);
self.constrain_callee(&callee);
self.constrain_call(expr, None, args.iter().map(|e| &*e));
}
@ -812,7 +814,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
// adjustments*.
//
// FIXME(#6268) nested method calls requires that this rule change
let ty0 = self.resolve_node_type(expr.id);
let ty0 = self.resolve_node_type(expr.hir_id);
self.type_must_outlive(infer::AddrOf(expr.span), ty0, expr_region);
intravisit::walk_expr(self, expr);
}
@ -849,7 +851,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
ret_expr.id, call_site_scope);
let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope.unwrap()));
self.type_of_node_must_outlive(infer::CallReturn(ret_expr.span),
ret_expr.id,
ret_expr.hir_id,
call_site_region);
intravisit::walk_expr(self, expr);
}
@ -870,8 +872,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
cast_expr,
source_expr);
let source_ty = self.resolve_node_type(source_expr.id);
let target_ty = self.resolve_node_type(cast_expr.id);
let source_ty = self.resolve_node_type(source_expr.hir_id);
let target_ty = self.resolve_node_type(cast_expr.hir_id);
self.walk_cast(cast_expr, source_ty, target_ty);
}
@ -915,11 +917,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
self.set_repeating_scope(repeating_scope);
}
fn constrain_callee(&mut self,
callee_id: ast::NodeId,
_call_expr: &hir::Expr,
_callee_expr: &hir::Expr) {
let callee_ty = self.resolve_node_type(callee_id);
fn constrain_callee(&mut self, callee_expr: &hir::Expr) {
let callee_ty = self.resolve_node_type(callee_expr.hir_id);
match callee_ty.sty {
ty::TyFnDef(..) | ty::TyFnPtr(_) => { }
_ => {
@ -962,14 +961,16 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
// ensure that any regions appearing in the argument type are
// valid for at least the lifetime of the function:
self.type_of_node_must_outlive(infer::CallArg(arg_expr.span),
arg_expr.id, callee_region);
arg_expr.hir_id,
callee_region);
}
// as loop above, but for receiver
if let Some(r) = receiver {
debug!("receiver: {:?}", r);
self.type_of_node_must_outlive(infer::CallRcvr(r.span),
r.id, callee_region);
r.hir_id,
callee_region);
}
}
@ -1038,7 +1039,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
//
// FIXME(#6268) remove to support nested method calls
self.type_of_node_must_outlive(infer::AutoBorrow(expr.span),
expr.id, expr_region);
expr.hir_id,
expr_region);
}
cmt = self.with_mc(|mc| mc.cat_expr_adjusted(expr, cmt, &adjustment))?;
@ -1109,21 +1111,27 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
/// adjustments) are valid for at least `minimum_lifetime`
fn type_of_node_must_outlive(&mut self,
origin: infer::SubregionOrigin<'tcx>,
id: ast::NodeId,
hir_id: hir::HirId,
minimum_lifetime: ty::Region<'tcx>)
{
// Try to resolve the type. If we encounter an error, then typeck
// is going to fail anyway, so just stop here and let typeck
// report errors later on in the writeback phase.
let ty0 = self.resolve_node_type(id);
let ty = self.tables.borrow().adjustments.get(&id)
.and_then(|adj| adj.last())
.map_or(ty0, |adj| adj.target);
let ty0 = self.resolve_node_type(hir_id);
let ty = {
let tables = self.tables.borrow();
tables.validate_hir_id(hir_id);
tables.adjustments
.get(&hir_id.local_id)
.and_then(|adj| adj.last())
.map_or(ty0, |adj| adj.target)
};
let ty = self.resolve_type(ty);
debug!("constrain_regions_in_type_of_node(\
ty={}, ty0={}, id={}, minimum_lifetime={:?})",
ty={}, ty0={}, id={:?}, minimum_lifetime={:?})",
ty, ty0,
id, minimum_lifetime);
hir_id, minimum_lifetime);
self.type_must_outlive(origin, ty, minimum_lifetime);
}
@ -1137,7 +1145,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
debug!("link_addr_of: cmt={:?}", cmt);
self.link_region_from_node_type(expr.span, expr.id, mutability, cmt);
self.link_region_from_node_type(expr.span, expr.hir_id, mutability, cmt);
}
/// Computes the guarantors for any ref bindings in a `let` and
@ -1173,7 +1181,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
fn link_fn_args(&self, body_scope: CodeExtent, args: &[hir::Arg]) {
debug!("regionck::link_fn_args(body_scope={:?})", body_scope);
for arg in args {
let arg_ty = self.node_ty(arg.id);
let arg_ty = self.node_ty(arg.hir_id);
let re_scope = self.tcx.mk_region(ty::ReScope(body_scope));
let arg_cmt = self.with_mc(|mc| {
mc.cat_rvalue(arg.id, arg.pat.span, re_scope, arg_ty)
@ -1200,7 +1208,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
let bm = *mc.tables.pat_binding_modes.get(&sub_pat.id)
.expect("missing binding mode");
if let ty::BindByReference(mutbl) = bm {
self.link_region_from_node_type(sub_pat.span, sub_pat.id,
self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id,
mutbl, sub_cmt);
}
}
@ -1236,7 +1244,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
/// which must be some reference (`&T`, `&str`, etc).
fn link_region_from_node_type(&self,
span: Span,
id: ast::NodeId,
id: hir::HirId,
mutbl: hir::Mutability,
cmt_borrowed: mc::cmt<'tcx>) {
debug!("link_region_from_node_type(id={:?}, mutbl={:?}, cmt_borrowed={:?})",

View File

@ -78,7 +78,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> {
hir::ExprClosure(cc, _, body_id, _) => {
let body = self.fcx.tcx.hir.body(body_id);
self.visit_body(body);
self.fcx.analyze_closure(expr.id, expr.span, body, cc);
self.fcx.analyze_closure((expr.id, expr.hir_id), expr.span, body, cc);
}
_ => { }
@ -90,7 +90,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn analyze_closure(&self,
id: ast::NodeId,
(id, hir_id): (ast::NodeId, hir::HirId),
span: Span,
body: &hir::Body,
capture_clause: hir::CaptureClause) {
@ -172,7 +172,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// inference algorithm will reject it).
// Extract the type variables UV0...UVn.
let (def_id, closure_substs) = match self.node_ty(id).sty {
let (def_id, closure_substs) = match self.node_ty(hir_id).sty {
ty::TyClosure(def_id, substs) => (def_id, substs),
ref t => {
span_bug!(
@ -216,7 +216,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
freevars.iter().map(|freevar| {
let def_id = freevar.def.def_id();
let var_id = tcx.hir.as_local_node_id(def_id).unwrap();
let freevar_ty = self.node_ty(var_id);
let freevar_ty = self.node_ty(tcx.hir.node_to_hir_id(var_id));
let upvar_id = ty::UpvarId {
var_id: var_id,
closure_expr_id: closure_id

View File

@ -35,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, arg.hir_id));
wbcx.visit_node_id(arg.pat.span, arg.hir_id);
}
wbcx.visit_body(body);
wbcx.visit_upvar_borrow_map();
@ -90,10 +90,11 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
self.fcx.tcx
}
fn write_ty_to_tables(&mut self, node_id: ast::NodeId, ty: Ty<'gcx>) {
debug!("write_ty_to_tables({}, {:?})", node_id, ty);
fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'gcx>) {
debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
assert!(!ty.needs_infer());
self.tables.node_types.insert(node_id, ty);
self.tables.validate_hir_id(hir_id);
self.tables.node_types.insert(hir_id.local_id, ty);
}
// Hacky hack: During type-checking, we treat *all* operators
@ -104,39 +105,39 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
match e.node {
hir::ExprUnary(hir::UnNeg, ref inner) |
hir::ExprUnary(hir::UnNot, ref inner) => {
let inner_ty = self.fcx.node_ty(inner.id);
let inner_ty = self.fcx.node_ty(inner.hir_id);
let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty);
if inner_ty.is_scalar() {
let mut tables = self.fcx.tables.borrow_mut();
tables.validate_hir_id(e.hir_id);
tables.type_dependent_defs.remove(&e.hir_id.local_id);
tables.node_substs.remove(&e.id);
tables.node_substs.remove(&e.hir_id.local_id);
}
}
hir::ExprBinary(ref op, ref lhs, ref rhs) |
hir::ExprAssignOp(ref op, ref lhs, ref rhs) => {
let lhs_ty = self.fcx.node_ty(lhs.id);
let lhs_ty = self.fcx.node_ty(lhs.hir_id);
let lhs_ty = self.fcx.resolve_type_vars_if_possible(&lhs_ty);
let rhs_ty = self.fcx.node_ty(rhs.id);
let rhs_ty = self.fcx.node_ty(rhs.hir_id);
let rhs_ty = self.fcx.resolve_type_vars_if_possible(&rhs_ty);
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
let mut tables = self.fcx.tables.borrow_mut();
tables.validate_hir_id(e.hir_id);
tables.type_dependent_defs.remove(&e.hir_id.local_id);
tables.node_substs.remove(&e.id);
tables.node_substs.remove(&e.hir_id.local_id);
match e.node {
hir::ExprBinary(..) => {
if !op.node.is_by_value() {
tables.adjustments.get_mut(&lhs.id).map(|a| a.pop());
tables.adjustments.get_mut(&rhs.id).map(|a| a.pop());
tables.adjustments.get_mut(&lhs.hir_id.local_id).map(|a| a.pop());
tables.adjustments.get_mut(&rhs.hir_id.local_id).map(|a| a.pop());
}
},
hir::ExprAssignOp(..) => {
tables.adjustments.get_mut(&lhs.id).map(|a| a.pop());
tables.adjustments.get_mut(&lhs.hir_id.local_id).map(|a| a.pop());
},
_ => {},
}
@ -163,12 +164,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, e.hir_id));
self.visit_node_id(e.span, 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, arg.hir_id));
self.visit_node_id(e.span, arg.hir_id);
}
self.visit_body(body);
@ -178,7 +179,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, b.hir_id));
self.visit_node_id(b.span, b.hir_id);
intravisit::walk_block(self, b);
}
@ -192,7 +193,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
_ => {}
};
self.visit_node_id(p.span, (p.id, p.hir_id));
self.visit_node_id(p.span, p.hir_id);
intravisit::walk_pat(self, p);
}
@ -200,7 +201,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
intravisit::walk_local(self, l);
let var_ty = self.fcx.local_ty(l.span, l.id);
let var_ty = self.resolve(&var_ty, &l.span);
self.write_ty_to_tables(l.id, var_ty);
self.write_ty_to_tables(l.hir_id, var_ty);
}
}
@ -279,13 +280,13 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}
});
self.tables.node_types.insert(node_id, outside_ty);
let hir_id = self.tcx().hir.node_to_hir_id(node_id);
self.tables.validate_hir_id(hir_id);
self.tables.node_types.insert(hir_id.local_id, outside_ty);
}
}
fn visit_node_id(&mut self,
span: Span,
(node_id, hir_id): (ast::NodeId, hir::HirId)) {
fn visit_node_id(&mut self, span: Span, hir_id: hir::HirId) {
{
let mut fcx_tables = self.fcx.tables.borrow_mut();
fcx_tables.validate_hir_id(hir_id);
@ -297,34 +298,39 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
}
// Resolve any borrowings for the node with id `node_id`
self.visit_adjustments(span, node_id);
self.visit_adjustments(span, hir_id);
// Resolve the type of the node with id `node_id`
let n_ty = self.fcx.node_ty(node_id);
let n_ty = self.fcx.node_ty(hir_id);
let n_ty = self.resolve(&n_ty, &span);
self.write_ty_to_tables(node_id, n_ty);
debug!("Node {} has type {:?}", node_id, n_ty);
self.write_ty_to_tables(hir_id, n_ty);
debug!("Node {:?} has type {:?}", hir_id, n_ty);
// Resolve any substitutions
if let Some(&substs) = self.fcx.tables.borrow().node_substs.get(&node_id) {
if let Some(&substs) = self.fcx.tables.borrow().node_substs.get(&hir_id.local_id) {
let substs = self.resolve(&substs, &span);
debug!("write_substs_to_tcx({}, {:?})", node_id, substs);
debug!("write_substs_to_tcx({:?}, {:?})", hir_id, substs);
assert!(!substs.needs_infer());
self.tables.node_substs.insert(node_id, substs);
self.tables.node_substs.insert(hir_id.local_id, substs);
}
}
fn visit_adjustments(&mut self, span: Span, node_id: ast::NodeId) {
let adjustment = self.fcx.tables.borrow_mut().adjustments.remove(&node_id);
fn visit_adjustments(&mut self, span: Span, hir_id: hir::HirId) {
let adjustment = {
let mut fcx_tables = self.fcx.tables.borrow_mut();
fcx_tables.validate_hir_id(hir_id);
fcx_tables.adjustments.remove(&hir_id.local_id)
};
match adjustment {
None => {
debug!("No adjustments for node {}", node_id);
debug!("No adjustments for node {:?}", hir_id);
}
Some(adjustment) => {
let resolved_adjustment = self.resolve(&adjustment, &span);
debug!("Adjustments for node {}: {:?}", node_id, resolved_adjustment);
self.tables.adjustments.insert(node_id, resolved_adjustment);
debug!("Adjustments for node {:?}: {:?}", hir_id, resolved_adjustment);
self.tables.validate_hir_id(hir_id);
self.tables.adjustments.insert(hir_id.local_id, resolved_adjustment);
}
}
}

View File

@ -1187,7 +1187,8 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
NodeTy(&hir::Ty { node: TyImplTrait(..), .. }) => {
let owner = tcx.hir.get_parent_did(node_id);
tcx.typeck_tables_of(owner).node_id_to_type(node_id)
let hir_id = tcx.hir.node_to_hir_id(node_id);
tcx.typeck_tables_of(owner).node_id_to_type(hir_id)
}
x => {