VariantCtor(DefId, CtorKind),
Method(DefId),
AssociatedConst(DefId),
- Local(DefId),
- Upvar(DefId, // def id of closed over local
+
+ Local(ast::NodeId),
+ Upvar(ast::NodeId, // node id of closed over local
usize, // index in the freevars list of the closure
ast::NodeId), // expr node that creates the closure
Label(ast::NodeId),
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) | Def::TyAlias(id) |
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
- Def::AssociatedConst(id) | Def::Local(id) | Def::Upvar(id, ..) | Def::Macro(id, ..) |
+ Def::AssociatedConst(id) | Def::Macro(id, ..) |
Def::GlobalAsm(id) => {
id
}
+ Def::Local(..) |
+ Def::Upvar(..) |
Def::Label(..) |
Def::PrimTy(..) |
Def::SelfTy(..) |
PatKind::Ref(ref subpattern, _) => {
visitor.visit_pat(subpattern)
}
- PatKind::Binding(_, def_id, ref pth1, ref optional_subpattern) => {
- visitor.visit_def_mention(Def::Local(def_id));
+ PatKind::Binding(_, canonical_id, ref pth1, ref optional_subpattern) => {
+ visitor.visit_def_mention(Def::Local(canonical_id));
visitor.visit_name(pth1.span, pth1.node);
walk_list!(visitor, visit_pat, optional_subpattern);
}
//! in the HIR, especially for multiple identifiers.
use hir;
-use hir::map::{Definitions, DefKey, REGULAR_SPACE};
-use hir::map::definitions::DefPathData;
+use hir::map::{Definitions, DefKey};
use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX};
use hir::def::{Def, PathResolution};
use lint::builtin::PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES;
node: match p.node {
PatKind::Wild => hir::PatKind::Wild,
PatKind::Ident(ref binding_mode, pth1, ref sub) => {
- self.with_parent_def(p.id, |this| {
- match this.resolver.get_resolution(p.id).map(|d| d.base_def()) {
- // `None` can occur in body-less function signatures
- def @ None | def @ Some(Def::Local(_)) => {
- let def_id = def.map(|d| d.def_id()).unwrap_or_else(|| {
- this.resolver.definitions().local_def_id(p.id)
- });
- hir::PatKind::Binding(this.lower_binding_mode(binding_mode),
- def_id,
- respan(pth1.span, pth1.node.name),
- sub.as_ref().map(|x| this.lower_pat(x)))
- }
- Some(def) => {
- hir::PatKind::Path(hir::QPath::Resolved(None, P(hir::Path {
- span: pth1.span,
- def,
- segments: hir_vec![
- hir::PathSegment::from_name(pth1.node.name)
- ],
- })))
- }
+ match self.resolver.get_resolution(p.id).map(|d| d.base_def()) {
+ // `None` can occur in body-less function signatures
+ def @ None | def @ Some(Def::Local(_)) => {
+ let canonical_id = match def {
+ Some(Def::Local(id)) => id,
+ _ => p.id
+ };
+ hir::PatKind::Binding(self.lower_binding_mode(binding_mode),
+ canonical_id,
+ respan(pth1.span, pth1.node.name),
+ sub.as_ref().map(|x| self.lower_pat(x)))
}
- })
+ Some(def) => {
+ hir::PatKind::Path(hir::QPath::Resolved(None, P(hir::Path {
+ span: pth1.span,
+ def,
+ segments: hir_vec![
+ hir::PathSegment::from_name(pth1.node.name)
+ ],
+ })))
+ }
+ }
}
PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
PatKind::TupleStruct(ref path, ref pats, ddpos) => {
id: Name,
binding: NodeId,
attrs: ThinVec<Attribute>) -> hir::Expr {
- let def = {
- let defs = self.resolver.definitions();
- Def::Local(defs.local_def_id(binding))
- };
-
let expr_path = hir::ExprPath(hir::QPath::Resolved(None, P(hir::Path {
span,
- def,
+ def: Def::Local(binding),
segments: hir_vec![hir::PathSegment::from_name(id)],
})));
fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingAnnotation)
-> P<hir::Pat> {
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.as_str());
- 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: node_id,
hir_id,
node: hir::PatKind::Binding(bm,
- def_id,
+ node_id,
Spanned {
span,
node: name,
}
fn visit_pat(&mut self, pat: &'a Pat) {
- let parent_def = self.parent_def;
-
match pat.node {
PatKind::Mac(..) => return self.visit_macro_invoc(pat.id, false),
- PatKind::Ident(_, id, _) => {
- let def = self.create_def(pat.id,
- DefPathData::Binding(id.node.name.as_str()),
- REGULAR_SPACE);
- self.parent_def = Some(def);
- }
- _ => {}
+ _ => visit::walk_pat(self, pat),
}
-
- visit::walk_pat(self, pat);
- self.parent_def = parent_def;
}
fn visit_expr(&mut self, expr: &'a Expr) {
DefPathData::TypeParam(name) |
DefPathData::LifetimeDef(name) |
DefPathData::EnumVariant(name) |
- DefPathData::Binding(name) |
DefPathData::Field(name) |
DefPathData::GlobalMetaData(name) => {
name.hash(&mut hasher);
StructCtor,
/// Initializer for a const
Initializer,
- /// Pattern binding
- Binding(InternedString),
/// An `impl Trait` type node.
ImplTrait,
/// A `typeof` type node.
TypeParam(name) |
LifetimeDef(name) |
EnumVariant(name) |
- Binding(name) |
Field(name) |
GlobalMetaData(name) => Some(name),
TypeParam(name) |
LifetimeDef(name) |
EnumVariant(name) |
- Binding(name) |
Field(name) |
GlobalMetaData(name) => {
return name
Wild,
/// A fresh binding `ref mut binding @ OPT_SUBPATTERN`.
- /// The `DefId` is for the definition of the variable being bound.
- Binding(BindingAnnotation, DefId, Spanned<Name>, Option<P<Pat>>),
+ /// The `NodeId` is the canonical ID for the variable being bound,
+ /// e.g. in `Ok(x) | Err(x)`, both `x` use the same canonical ID,
+ /// which is the pattern ID of the first `x`.
+ Binding(BindingAnnotation, NodeId, Spanned<Name>, Option<P<Pat>>),
/// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
/// The `bool` is `true` in the presence of a `..`.
pub span: Span
}
+impl Freevar {
+ pub fn var_id(&self) -> NodeId {
+ match self.def {
+ Def::Local(id) | Def::Upvar(id, ..) => id,
+ _ => bug!("Freevar::var_id: bad def ({:?})", self.def)
+ }
+ }
+}
+
pub type FreevarMap = NodeMap<Vec<Freevar>>;
pub type CaptureModeMap = NodeMap<CaptureClause>;
name)
}
infer::UpvarRegion(ref upvar_id, _) => {
- format!(" for capture of `{}` by closure",
- self.tcx.local_var_name_str_def_index(upvar_id.var_id))
+ let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id);
+ let var_name = self.tcx.hir.name(var_node_id);
+ format!(" for capture of `{}` by closure", var_name)
}
};
"...so that reference does not outlive borrowed content");
}
infer::ReborrowUpvar(span, ref upvar_id) => {
+ let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id);
+ let var_name = self.tcx.hir.name(var_node_id);
err.span_note(span,
- &format!("...so that closure can access `{}`",
- self.tcx
- .local_var_name_str_def_index(upvar_id.var_id)));
+ &format!("...so that closure can access `{}`", var_name));
}
infer::InfStackClosure(span) => {
err.span_note(span, "...so that closure does not outlive its stack frame");
err.span_note(span,
&format!("...so that captured variable `{}` does not outlive the \
enclosing closure",
- self.tcx.local_var_name_str(id)));
+ self.tcx.hir.name(id)));
}
infer::IndexSlice(span) => {
err.span_note(span, "...so that slice is not indexed outside the lifetime");
err
}
infer::ReborrowUpvar(span, ref upvar_id) => {
+ let var_node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id);
+ let var_name = self.tcx.hir.name(var_node_id);
let mut err = struct_span_err!(self.tcx.sess,
span,
E0313,
"lifetime of borrowed pointer outlives lifetime \
of captured variable `{}`...",
- self.tcx
- .local_var_name_str_def_index(upvar_id.var_id));
+ var_name);
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"...the borrowed pointer is valid for ",
sub,
self.tcx.note_and_explain_region(
region_scope_tree,
&mut err,
- &format!("...but `{}` is only valid for ",
- self.tcx.local_var_name_str_def_index(upvar_id.var_id)),
+ &format!("...but `{}` is only valid for ", var_name),
sup,
"");
err
E0474,
"captured variable `{}` does not outlive the \
enclosing closure",
- self.tcx.local_var_name_str(id));
+ self.tcx.hir.name(id));
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
"captured variable is valid for ", sup, "");
self.tcx.note_and_explain_region(region_scope_tree, &mut err,
self.check_def_id(def.def_id());
}
_ if self.ignore_non_const_paths => (),
- Def::PrimTy(..) | Def::SelfTy(..) => (),
+ Def::PrimTy(..) | Def::SelfTy(..) |
+ Def::Local(..) | Def::Upvar(..) => {}
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {
self.check_def_id(enum_id);
let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
- if let PatKind::Binding(_, def_id, ..) = pat.node {
+ if let PatKind::Binding(_, canonical_id, ..) = pat.node {
debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode);
let bm = *mc.tables.pat_binding_modes().get(pat.hir_id)
.expect("missing binding mode");
// Each match binding is effectively an assignment to the
// binding being produced.
- let def = Def::Local(def_id);
+ let def = Def::Local(canonical_id);
if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) {
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
}
self.tcx().with_freevars(closure_expr.id, |freevars| {
for freevar in freevars {
- let var_def_id = freevar.def.def_id();
- debug_assert!(var_def_id.is_local());
+ let var_hir_id = self.tcx().hir.node_to_hir_id(freevar.var_id());
let closure_def_id = self.tcx().hir.local_def_id(closure_expr.id);
let upvar_id = ty::UpvarId {
- var_id: var_def_id.index,
+ var_id: var_hir_id,
closure_expr_id: closure_def_id.index
};
let upvar_capture = self.mc.tables.upvar_capture(upvar_id);
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
fn_decl_span,
- freevar.def));
+ freevar));
match upvar_capture {
ty::UpvarCapture::ByValue => {
let mode = copy_or_move(&self.mc,
fn cat_captured_var(&mut self,
closure_id: ast::NodeId,
closure_span: Span,
- upvar_def: Def)
+ upvar: &hir::Freevar)
-> mc::McResult<mc::cmt<'tcx>> {
// Create the cmt for the variable being borrowed, from the
// caller's perspective
- 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_hir_id = self.tcx().hir.node_to_hir_id(upvar.var_id());
let var_ty = self.mc.node_ty(var_hir_id)?;
- self.mc.cat_def(closure_id, closure_span, var_ty, upvar_def)
+ self.mc.cat_def(closure_id, closure_span, var_ty, upvar.def)
}
}
let mut call_caps = Vec::new();
ir.tcx.with_freevars(expr.id, |freevars| {
for fv in freevars {
- if let Def::Local(def_id) = fv.def {
- let rv = ir.tcx.hir.as_local_node_id(def_id).unwrap();
+ if let Def::Local(rv) = fv.def {
let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
call_caps.push(CaptureInfo {ln: fv_ln,
var_nid: rv});
fn access_path(&mut self, id: NodeId, path: &hir::Path, succ: LiveNode, acc: u32)
-> LiveNode {
match path.def {
- Def::Local(def_id) => {
- let nid = self.ir.tcx.hir.as_local_node_id(def_id).unwrap();
+ Def::Local(nid) => {
self.access_var(id, nid, succ, acc, path.span)
}
_ => succ
fn check_lvalue(&mut self, expr: &'tcx Expr) {
match expr.node {
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
- if let Def::Local(def_id) = path.def {
+ if let Def::Local(nid) = path.def {
// Assignment to an immutable variable or argument: only legal
// if there is no later assignment. If this local is actually
// mutable, then check for a reassignment to flag the mutability
// as being used.
- let nid = self.ir.tcx.hir.as_local_node_id(def_id).unwrap();
let ln = self.live_node(expr.id, expr.span);
let var = self.variable(nid, expr.span);
self.warn_about_dead_assign(expr.span, expr.id, ln, var);
}))
}
- Def::Upvar(def_id, _, fn_node_id) => {
- let var_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
+ Def::Upvar(var_id, _, fn_node_id) => {
self.cat_upvar(id, span, var_id, fn_node_id)
}
- Def::Local(def_id) => {
- let vid = self.tcx.hir.as_local_node_id(def_id).unwrap();
+ Def::Local(vid) => {
Ok(Rc::new(cmt_ {
id,
span,
};
let closure_expr_def_index = self.tcx.hir.local_def_id(fn_node_id).index;
- let var_def_index = self.tcx.hir.local_def_id(var_id).index;
-
+ let var_hir_id = self.tcx.hir.node_to_hir_id(var_id);
let upvar_id = ty::UpvarId {
- var_id: var_def_index,
+ var_id: var_hir_id,
closure_expr_id: closure_expr_def_index
};
- 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
Categorization::StaticItem => write!(f, "static"),
Categorization::Rvalue(r) => { write!(f, "rvalue({:?})", r) }
Categorization::Local(id) => {
- let name = ty::tls::with(|tcx| tcx.local_var_name_str(id));
+ let name = ty::tls::with(|tcx| tcx.hir.name(id));
write!(f, "local({})", name)
}
Categorization::Upvar(upvar) => {
_ => None
};
- if let Some(def) = def {
- let def_id = def.def_id();
- if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
- if self.def_id_represents_local_inlined_item(def_id) {
- self.worklist.push(node_id);
- } else {
- match def {
- // If this path leads to a constant, then we need to
- // recurse into the constant to continue finding
- // items that are reachable.
- Def::Const(..) | Def::AssociatedConst(..) => {
- self.worklist.push(node_id);
- }
+ match def {
+ Some(Def::Local(node_id)) | Some(Def::Upvar(node_id, ..)) => {
+ self.reachable_symbols.insert(node_id);
+ }
+ Some(def) => {
+ let def_id = def.def_id();
+ if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
+ if self.def_id_represents_local_inlined_item(def_id) {
+ self.worklist.push(node_id);
+ } else {
+ match def {
+ // If this path leads to a constant, then we need to
+ // recurse into the constant to continue finding
+ // items that are reachable.
+ Def::Const(..) | Def::AssociatedConst(..) => {
+ self.worklist.push(node_id);
+ }
- // If this wasn't a static, then the destination is
- // surely reachable.
- _ => {
- self.reachable_symbols.insert(node_id);
+ // If this wasn't a static, then the destination is
+ // surely reachable.
+ _ => {
+ self.reachable_symbols.insert(node_id);
+ }
}
}
}
}
+ _ => {}
}
intravisit::walk_expr(self, expr)
fn visit_path(&mut self, path: &'tcx hir::Path, id: ast::NodeId) {
match path.def {
+ Def::Local(..) | Def::Upvar(..) |
Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => {}
_ => self.tcx.check_stability(path.def.def_id(), id, path.span)
}
tcx.with_freevars(node_id, |freevars| {
for (freevar, lv) in freevars.iter().zip(lvs) {
- let def_id = freevar.def.def_id();
- let var_id = tcx.hir.as_local_node_id(def_id).unwrap();
- let var_name = tcx.local_var_name_str(var_id);
- struct_fmt.field(&var_name, lv);
+ let var_name = tcx.hir.name(freevar.var_id());
+ struct_fmt.field(&var_name.as_str(), lv);
}
});
tcx.with_freevars(node_id, |freevars| {
for (freevar, lv) in freevars.iter().zip(lvs) {
- let def_id = freevar.def.def_id();
- let var_id = tcx.hir.as_local_node_id(def_id).unwrap();
- let var_name = tcx.local_var_name_str(var_id);
- struct_fmt.field(&var_name, lv);
+ let var_name = tcx.hir.name(freevar.var_id());
+ struct_fmt.field(&var_name.as_str(), lv);
}
struct_fmt.field("$state", &lvs[freevars.len()]);
for i in (freevars.len() + 1)..lvs.len() {
let local_id_root =
local_id_root.expect("trying to hash invalid TypeckTables");
- let var_def_id = DefId {
+ let var_owner_def_id = DefId {
krate: local_id_root.krate,
- index: var_id,
+ index: var_id.owner,
};
let closure_def_id = DefId {
krate: local_id_root.krate,
index: closure_expr_id,
};
- (hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
+ ((hcx.def_path_hash(var_owner_def_id), var_id.local_id),
+ hcx.def_path_hash(closure_def_id))
});
ich::hash_stable_itemlocalmap(hcx, hasher, closure_tys);
data @ DefPathData::Initializer |
data @ DefPathData::MacroDef(..) |
data @ DefPathData::ClosureExpr |
- data @ DefPathData::Binding(..) |
data @ DefPathData::ImplTrait |
data @ DefPathData::Typeof |
data @ DefPathData::GlobalMetaData(..) => {
/// by the upvar) and the id of the closure expression.
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct UpvarId {
- pub var_id: DefIndex,
+ pub var_id: hir::HirId,
pub closure_expr_id: DefIndex,
}
}
}
- pub fn local_var_name_str(self, id: NodeId) -> InternedString {
- match self.hir.find(id) {
- Some(hir_map::NodeBinding(pat)) => {
- match pat.node {
- hir::PatKind::Binding(_, _, ref path1, _) => path1.node.as_str(),
- _ => {
- bug!("Variable id {} maps to {:?}, not local", id, pat);
- },
- }
- },
- r => bug!("Variable id {} maps to {:?}, not local", id, r),
- }
- }
-
- pub fn local_var_name_str_def_index(self, def_index: DefIndex) -> InternedString {
- let node_id = self.hir.as_local_node_id(DefId::local(def_index)).unwrap();
- self.local_var_name_str(node_id)
- }
-
pub fn expr_is_lval(self, expr: &hir::Expr) -> bool {
match expr.node {
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
let mut sep = " ";
tcx.with_freevars(node_id, |freevars| {
for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {
- let def_id = freevar.def.def_id();
- let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
write!(f,
"{}{}:{}",
sep,
- tcx.local_var_name_str(node_id),
+ tcx.hir.name(freevar.var_id()),
upvar_ty)?;
sep = ", ";
}
let mut sep = " ";
tcx.with_freevars(node_id, |freevars| {
for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {
- let def_id = freevar.def.def_id();
- let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
write!(f,
"{}{}:{}",
sep,
- tcx.local_var_name_str(node_id),
+ tcx.hir.name(freevar.var_id()),
upvar_ty)?;
sep = ", ";
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "UpvarId({:?};`{}`;{:?})",
self.var_id,
- ty::tls::with(|tcx| tcx.local_var_name_str_def_index(self.var_id)),
+ ty::tls::with(|tcx| tcx.hir.name(tcx.hir.hir_to_node_id(self.var_id))),
self.closure_expr_id)
}
}
None
}
LpUpvar(ty::UpvarId{ var_id, closure_expr_id: _ }) => {
- let local_id = self.tcx().hir.def_index_to_node_id(var_id);
+ let local_id = self.tcx().hir.hir_to_node_id(var_id);
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
None
}
}
}
if let NoteClosureEnv(upvar_id) = error.move_from.note {
- let var_node_id = bccx.tcx.hir.def_index_to_node_id(upvar_id.var_id);
+ let var_node_id = bccx.tcx.hir.hir_to_node_id(upvar_id.var_id);
err.span_label(bccx.tcx.hir.span(var_node_id),
"captured outer variable");
}
out: &mut String) {
match loan_path.kind {
LpUpvar(ty::UpvarId { var_id: id, closure_expr_id: _ }) => {
- out.push_str(&self.tcx.local_var_name_str_def_index(id));
+ out.push_str(&self.tcx.hir.name(self.tcx.hir.hir_to_node_id(id)).as_str());
}
LpVar(id) => {
- out.push_str(&self.tcx.local_var_name_str(id));
+ out.push_str(&self.tcx.hir.name(id).as_str());
}
LpDowncast(ref lp_base, variant_def_id) => {
LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => {
let s = ty::tls::with(|tcx| {
- let var_node_id = tcx.hir.def_index_to_node_id(var_id);
+ let var_node_id = tcx.hir.hir_to_node_id(var_id);
tcx.hir.node_to_string(var_node_id)
});
write!(f, "$({} captured by id={:?})", s, closure_expr_id)
LpUpvar(ty::UpvarId{ var_id, closure_expr_id: _ }) => {
let s = ty::tls::with(|tcx| {
- let var_node_id = tcx.hir.def_index_to_node_id(var_id);
+ let var_node_id = tcx.hir.hir_to_node_id(var_id);
tcx.hir.node_to_string(var_node_id)
});
write!(f, "$({} captured by closure)", s)
use rustc::ty::util::IntTypeExt;
use rustc::ty::subst::{Substs, Subst};
use rustc::util::common::ErrorReported;
-use rustc::util::nodemap::DefIdMap;
+use rustc::util::nodemap::NodeMap;
use syntax::abi::Abi;
use syntax::ast;
tables: &'a ty::TypeckTables<'tcx>,
param_env: ty::ParamEnv<'tcx>,
substs: &'tcx Substs<'tcx>,
- fn_args: Option<DefIdMap<ConstVal<'tcx>>>
+ fn_args: Option<NodeMap<ConstVal<'tcx>>>
}
impl<'a, 'tcx> ConstContext<'a, 'tcx> {
Def::StructCtor(_, CtorKind::Fn) => {
signal!(e, UnimplementedConstVal("tuple struct constructors"))
}
- Def::Local(def_id) => {
- debug!("Def::Local({:?}): {:?}", def_id, cx.fn_args);
- if let Some(val) = cx.fn_args.as_ref().and_then(|args| args.get(&def_id)) {
+ Def::Local(id) => {
+ debug!("Def::Local({:?}): {:?}", id, cx.fn_args);
+ if let Some(val) = cx.fn_args.as_ref().and_then(|args| args.get(&id)) {
val.clone()
} else {
signal!(e, NonConstPath);
}
};
- let arg_defs = body.arguments.iter().map(|arg| match arg.pat.node {
- hir::PatKind::Binding(_, def_id, _, _) => Some(def_id),
+ let arg_ids = body.arguments.iter().map(|arg| match arg.pat.node {
+ hir::PatKind::Binding(_, canonical_id, _, _) => Some(canonical_id),
_ => None
}).collect::<Vec<_>>();
- assert_eq!(arg_defs.len(), args.len());
+ assert_eq!(arg_ids.len(), args.len());
- let mut call_args = DefIdMap();
- for (arg, arg_expr) in arg_defs.into_iter().zip(args.iter()) {
+ let mut call_args = NodeMap();
+ for (arg, arg_expr) in arg_ids.into_iter().zip(args.iter()) {
let arg_val = cx.eval(arg_expr)?;
debug!("const call arg: {:?}", arg);
- if let Some(def_id) = arg {
- assert!(call_args.insert(def_id, arg_val).is_none());
+ if let Some(id) = arg {
+ assert!(call_args.insert(id, arg_val).is_none());
}
}
debug!("const call({:?})", call_args);
}
}
- PatKind::Binding(_, def_id, ref ident, ref sub) => {
- let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
+ PatKind::Binding(_, id, ref ident, ref sub) => {
let var_ty = self.tables.node_id_to_type(pat.hir_id);
let region = match var_ty.sty {
ty::TyRef(r, _) => Some(r),
} else {
return false;
};
- def.def_id() == cx.tcx.hir.local_def_id(fn_id)
+ match def {
+ Def::Local(..) | Def::Upvar(..) => false,
+ _ => def.def_id() == cx.tcx.hir.local_def_id(fn_id)
+ }
}
_ => false,
}
// Gather the upvars of a closure, if any.
let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| {
freevars.iter().map(|fv| {
- let var_def_id = fv.def.def_id();
- let var_node_id = tcx.hir.as_local_node_id(var_def_id).unwrap();
+ let var_id = fv.var_id();
+ let var_hir_id = tcx.hir.node_to_hir_id(var_id);
let closure_expr_id = tcx.hir.local_def_id(fn_id).index;
let capture = hir.tables().upvar_capture(ty::UpvarId {
- var_id: var_def_id.index,
+ var_id: var_hir_id,
closure_expr_id,
});
let by_ref = match capture {
debug_name: keywords::Invalid.name(),
by_ref,
};
- if let Some(hir::map::NodeBinding(pat)) = tcx.hir.find(var_node_id) {
+ if let Some(hir::map::NodeBinding(pat)) = tcx.hir.find(var_id) {
if let hir::PatKind::Binding(_, _, ref ident, _) = pat.node {
decl.debug_name = ident.node;
}
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
match def {
- Def::Local(def_id) => {
- let node_id = cx.tcx.hir.as_local_node_id(def_id).unwrap();
- ExprKind::VarRef { id: node_id }
- }
+ Def::Local(id) => ExprKind::VarRef { id },
- Def::Upvar(var_def_id, index, closure_expr_id) => {
- let id_var = cx.tcx.hir.as_local_node_id(var_def_id).unwrap();
+ Def::Upvar(var_id, index, closure_expr_id) => {
debug!("convert_var(upvar({:?}, {:?}, {:?}))",
- id_var,
+ var_id,
index,
closure_expr_id);
- let var_ty = cx.tables()
- .node_id_to_type(cx.tcx.hir.node_to_hir_id(id_var));
+ let var_hir_id = cx.tcx.hir.node_to_hir_id(var_id);
+ let var_ty = cx.tables().node_id_to_type(var_hir_id);
// FIXME free regions in closures are not right
let closure_ty = cx.tables()
// ...but the upvar might be an `&T` or `&mut T` capture, at which
// point we need an implicit deref
let upvar_id = ty::UpvarId {
- var_id: var_def_id.index,
+ var_id: var_hir_id,
closure_expr_id: closure_def_id.index,
};
match cx.tables().upvar_capture(upvar_id) {
freevar: &hir::Freevar,
freevar_ty: Ty<'tcx>)
-> ExprRef<'tcx> {
- let var_def_id = freevar.def.def_id();
- let var_node_id = cx.tcx.hir.as_local_node_id(var_def_id).unwrap();
+ let var_hir_id = cx.tcx.hir.node_to_hir_id(freevar.var_id());
let upvar_id = ty::UpvarId {
- var_id: var_def_id.index,
+ var_id: var_hir_id,
closure_expr_id: cx.tcx.hir.local_def_id(closure_expr.id).index,
};
let upvar_capture = cx.tables().upvar_capture(upvar_id);
let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);
- let var_ty = cx.tables()
- .node_id_to_type(cx.tcx.hir.node_to_hir_id(var_node_id));
+ let var_ty = cx.tables().node_id_to_type(var_hir_id);
let captured_var = Expr {
temp_lifetime,
ty: var_ty,
// must not add it if it's in the bindings map
// because that breaks the assumptions later
// passes make about or-patterns.)
- let mut def = Def::Local(self.definitions.local_def_id(pat_id));
+ let mut def = Def::Local(pat_id);
match bindings.get(&ident.node).cloned() {
Some(id) if id == outer_pat_id => {
// `Variant(a, a)`, error
Def::Upvar(..) => {
span_bug!(span, "unexpected {:?} in bindings", def)
}
- Def::Local(def_id) => {
+ Def::Local(node_id) => {
for rib in ribs {
match rib.kind {
NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) |
}
ClosureRibKind(function_id) => {
let prev_def = def;
- let node_id = self.definitions.as_local_node_id(def_id).unwrap();
let seen = self.freevars_seen
.entry(function_id)
.or_insert_with(|| NodeMap());
if let Some(&index) = seen.get(&node_id) {
- def = Def::Upvar(def_id, index, function_id);
+ def = Def::Upvar(node_id, index, function_id);
continue;
}
let vec = self.freevars
.entry(function_id)
.or_insert_with(|| vec![]);
let depth = vec.len();
- def = Def::Upvar(def_id, depth, function_id);
+ def = Def::Upvar(node_id, depth, function_id);
if record_used {
vec.push(Freevar {
}
// Fields are generally expected in the same contexts as locals.
- if filter_fn(Def::Local(DefId::local(CRATE_DEF_INDEX))) {
+ if filter_fn(Def::Local(ast::DUMMY_NODE_ID)) {
if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
// Look for a field with the same name in the current self_type.
if let Some(resolution) = self.def_map.get(&node_id) {
// process collected paths
for &(id, ref p, immut) in &collector.collected_paths {
match self.save_ctxt.get_path_def(id) {
- HirDef::Local(def_id) => {
- let id = self.tcx.hir.as_local_node_id(def_id).unwrap();
+ HirDef::Local(id) => {
let mut value = if immut == ast::Mutability::Immutable {
self.span.snippet(p.span).to_string()
} else {
use rustc::hir;
use rustc::hir::def::Def as HirDef;
use rustc::hir::map::{Node, NodeItem};
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{LOCAL_CRATE, DefId};
use rustc::session::config::CrateType::CrateTypeExecutable;
use rustc::ty::{self, TyCtxt};
use rustc_typeck::hir_ty_to_ty;
self.tables.qpath_def(qpath, hir_id)
}
- Node::NodeBinding(&hir::Pat { node: hir::PatKind::Binding(_, def_id, ..), .. }) => {
- HirDef::Local(def_id)
- }
+ Node::NodeBinding(&hir::Pat {
+ node: hir::PatKind::Binding(_, canonical_id, ..), ..
+ }) => HirDef::Local(canonical_id),
Node::NodeTy(ty) => {
if let hir::Ty { node: hir::TyPath(ref qpath), .. } = *ty {
let sub_span = self.span_utils.span_for_last_ident(path.span);
filter!(self.span_utils, sub_span, path.span, None);
match def {
- HirDef::Upvar(..) |
- HirDef::Local(..) |
+ HirDef::Upvar(id, ..) |
+ HirDef::Local(id) => {
+ let span = self.span_from_span(sub_span.unwrap());
+ Some(Ref {
+ kind: RefKind::Variable,
+ span,
+ ref_id: id_from_node_id(id, self),
+ })
+ }
HirDef::Static(..) |
HirDef::Const(..) |
HirDef::AssociatedConst(..) |
fn id_from_node_id(id: NodeId, scx: &SaveContext) -> rls_data::Id {
let def_id = scx.tcx.hir.opt_local_def_id(id);
- def_id.map(|id| id_from_def_id(id)).unwrap_or_else(null_id)
+ def_id.map(|id| id_from_def_id(id)).unwrap_or_else(|| {
+ // Create a *fake* `DefId` out of a `NodeId` by subtracting the `NodeId`
+ // out of the maximum u32 value. This will work unless you have *billions*
+ // of definitions in a single crate (very unlikely to actually happen).
+ rls_data::Id {
+ krate: LOCAL_CRATE.as_u32(),
+ index: !id.as_u32(),
+ }
+ })
}
fn null_id() -> rls_data::Id {
self.demand_eqtype(pat.span, expected, rhs_ty);
common_type
}
- PatKind::Binding(ba, def_id, _, ref sub) => {
+ PatKind::Binding(ba, var_id, _, ref sub) => {
// Note the binding mode in the typeck tables. For now, what we store is always
// identical to what could be scraped from the HIR, but this will change with
// default binding modes (#42640).
// if there are multiple arms, make sure they all agree on
// what the type of the binding `x` ought to be
- let var_id = tcx.hir.as_local_node_id(def_id).unwrap();
if var_id != pat.id {
let vt = self.local_ty(pat.span, var_id);
self.demand_eqtype(pat.span, vt, typ);
} else {
Def::Err
};
- if def != Def::Err {
- if let Some(span) = self.tcx.hir.span_if_local(def.def_id()) {
- err.span_note(span, "defined here");
+ let def_span = match def {
+ Def::Err => None,
+ Def::Local(id) | Def::Upvar(id, ..) => {
+ Some(self.tcx.hir.span(id))
}
+ _ => self.tcx.hir.span_if_local(def.def_id())
+ };
+ if let Some(span) = def_span {
+ err.span_note(span, "defined here");
}
}
AstConv::prohibit_type_params(self, &segments[..segments.len() - poly_segments]);
match def {
- Def::Local(def_id) | Def::Upvar(def_id, ..) => {
- let nid = self.tcx.hir.as_local_node_id(def_id).unwrap();
+ Def::Local(nid) | Def::Upvar(nid, ..) => {
let ty = self.local_ty(span, nid);
let ty = self.normalize_associated_types_in(span, &ty);
self.write_ty(self.tcx.hir.node_to_hir_id(node_id), ty);
self.tcx.with_freevars(closure_node_id, |freevars| {
for freevar in freevars {
- let var_def_id = freevar.def.def_id();
let upvar_id = ty::UpvarId {
- var_id: var_def_id.index,
+ var_id: self.tcx.hir.node_to_hir_id(freevar.var_id()),
closure_expr_id: closure_def_id.index,
};
debug!("seed upvar_id {:?}", upvar_id);
tcx.with_freevars(closure_id, |freevars| {
freevars.iter().map(|freevar| {
- let var_def_id = freevar.def.def_id();
- let var_node_id = tcx.hir.as_local_node_id(var_def_id).unwrap();
- let freevar_ty = self.node_ty(tcx.hir.node_to_hir_id(var_node_id));
+ let var_node_id = freevar.var_id();
+ let var_hir_id = tcx.hir.node_to_hir_id(var_node_id);
+ let freevar_ty = self.node_ty(var_hir_id);
let upvar_id = ty::UpvarId {
- var_id: var_def_id.index,
+ var_id: var_hir_id,
closure_expr_id: closure_def_index,
};
let capture = self.tables.borrow().upvar_capture(upvar_id);
}
}
-fn var_name(tcx: ty::TyCtxt, var_def_index: DefIndex) -> ast::Name {
- let var_node_id = tcx.hir.def_index_to_node_id(var_def_index);
+fn var_name(tcx: ty::TyCtxt, var_hir_id: hir::HirId) -> ast::Name {
+ let var_node_id = tcx.hir.hir_to_node_id(var_hir_id);
tcx.hir.name(var_node_id)
}
// START rustc.node50.EraseRegions.after.mir
// fn main::{{closure}}(_1: &ReErased [closure@NodeId(50)], _2: &ReErased mut i32) -> i32 {
// bb0: {
-// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:15) => validate_1/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(50)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:15) => validate_1/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
+// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:11) => validate_1/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(50)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:11) => validate_1/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
// StorageLive(_3);
// _3 = _2;
// StorageLive(_4);
// START rustc.node22.EraseRegions.after.mir
// fn write_42::{{closure}}(_1: &ReErased [closure@NodeId(22)], _2: *mut i32) -> () {
// bb0: {
-// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:11) => validate_4/8cd878b::write_42[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(22)], _2: *mut i32]);
-// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:11) => validate_4/8cd878b::write_42[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(22)], _2: *mut i32]);
+// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:9) => validate_4/8cd878b::write_42[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(22)], _2: *mut i32]);
+// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:9) => validate_4/8cd878b::write_42[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(22)], _2: *mut i32]);
// StorageLive(_3);
// _3 = _2;
// (*_3) = const 23i32;
// START rustc.node60.EraseRegions.after.mir
// fn main::{{closure}}(_1: &ReErased [closure@NodeId(60)], _2: &ReErased mut i32) -> bool {
// bb0: {
-// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:15) => validate_4/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:15) => validate_4/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
-// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:15) => validate_4/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:15) => validate_4/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
+// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:10) => validate_4/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:10) => validate_4/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
+// Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:10) => validate_4/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:10) => validate_4/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
// StorageLive(_3);
// _0 = const write_42(_4) -> bb1;
// }
// START rustc.node46.EraseRegions.after.mir
// fn main::{{closure}}(_1: &ReErased [closure@NodeId(46)], _2: &ReErased mut i32) -> bool {
// bb0: {
-// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:12) => validate_5/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(46)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:12) => validate_5/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
+// Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:9) => validate_5/8cd878b::main[0]::{{closure}}[0] }, "BrEnv") [closure@NodeId(46)], _2: &ReFree(DefId { krate: CrateNum(0), node: DefIndex(1:9) => validate_5/8cd878b::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
// StorageLive(_3);
// _3 = _2;
// StorageLive(_4);