Introduce LocalDefId which provides a type-level guarantee that the DefId is from the local crate.

This commit is contained in:
Michael Woerister 2017-11-16 14:04:01 +01:00
parent 2f50e626e1
commit 24e54ddefa
11 changed files with 98 additions and 31 deletions

View file

@ -92,6 +92,7 @@ impl serialize::UseSpecializedDecodable for CrateNum {
/// don't have to care about these ranges.
newtype_index!(DefIndex
{
ENCODABLE = custom
DEBUG_FORMAT = custom,
/// The start of the "high" range of DefIndexes.
@ -208,13 +209,20 @@ impl fmt::Debug for DefId {
impl DefId {
/// Make a local `DefId` with the given index.
#[inline]
pub fn local(index: DefIndex) -> DefId {
DefId { krate: LOCAL_CRATE, index: index }
}
pub fn is_local(&self) -> bool {
#[inline]
pub fn is_local(self) -> bool {
self.krate == LOCAL_CRATE
}
#[inline]
pub fn to_local(self) -> LocalDefId {
LocalDefId::from_def_id(self)
}
}
impl serialize::UseSpecializedEncodable for DefId {
@ -242,3 +250,33 @@ impl serialize::UseSpecializedDecodable for DefId {
})
}
}
#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct LocalDefId(DefIndex);
impl LocalDefId {
#[inline]
pub fn from_def_id(def_id: DefId) -> LocalDefId {
assert!(def_id.is_local());
LocalDefId(def_id.index)
}
#[inline]
pub fn to_def_id(self) -> DefId {
DefId {
krate: LOCAL_CRATE,
index: self.0
}
}
}
impl fmt::Debug for LocalDefId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.to_def_id().fmt(f)
}
}
impl serialize::UseSpecializedEncodable for LocalDefId {}
impl serialize::UseSpecializedDecodable for LocalDefId {}

View file

@ -17,7 +17,7 @@ pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
use dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex};
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndexAddressSpace};
use hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId, DefIndexAddressSpace};
use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId, CRATE_NODE_ID};
@ -359,6 +359,16 @@ impl<'hir> Map<'hir> {
self.definitions.as_local_node_id(DefId::local(def_index)).unwrap()
}
#[inline]
pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
self.definitions.def_index_to_hir_id(def_id.to_def_id().index)
}
#[inline]
pub fn local_def_id_to_node_id(&self, def_id: LocalDefId) -> NodeId {
self.definitions.as_local_node_id(def_id.to_def_id()).unwrap()
}
fn entry_count(&self) -> usize {
self.map.len()
}

View file

@ -13,7 +13,7 @@
use hir;
use hir::map::DefPathHash;
use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
use hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
use ich::{StableHashingContext, NodeIdHashingMode};
use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
StableHasher, StableHasherResult};
@ -38,6 +38,24 @@ impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for DefId {
}
}
impl<'gcx> HashStable<StableHashingContext<'gcx>> for LocalDefId {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
}
}
impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for LocalDefId {
type KeyType = DefPathHash;
#[inline]
fn to_stable_hash_key(&self, hcx: &StableHashingContext<'gcx>) -> DefPathHash {
hcx.def_path_hash(self.to_def_id())
}
}
impl<'gcx> HashStable<StableHashingContext<'gcx>> for CrateNum {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,

View file

@ -20,7 +20,7 @@ use self::TrackMatchMode::*;
use self::OverloadedCallType::*;
use hir::def::Def;
use hir::def_id::{DefId};
use hir::def_id::DefId;
use infer::InferCtxt;
use middle::mem_categorization as mc;
use middle::region;
@ -915,7 +915,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
let closure_def_id = self.tcx().hir.local_def_id(closure_expr.id);
let upvar_id = ty::UpvarId {
var_id: var_hir_id,
closure_expr_id: closure_def_id.index
closure_expr_id: closure_def_id.to_local(),
};
let upvar_capture = self.mc.tables.upvar_capture(upvar_id);
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,

View file

@ -70,7 +70,7 @@ pub use self::Note::*;
use self::Aliasability::*;
use middle::region;
use hir::def_id::{DefId, DefIndex};
use hir::def_id::{DefId, LocalDefId};
use hir::map as hir_map;
use infer::InferCtxt;
use hir::def::{Def, CtorKind};
@ -191,7 +191,7 @@ pub type cmt<'tcx> = Rc<cmt_<'tcx>>;
pub enum ImmutabilityBlame<'tcx> {
ImmLocal(ast::NodeId),
ClosureEnv(DefIndex),
ClosureEnv(LocalDefId),
LocalDeref(ast::NodeId),
AdtFieldDeref(&'tcx ty::AdtDef, &'tcx ty::FieldDef)
}
@ -758,11 +758,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
}
};
let closure_expr_def_index = self.tcx.hir.local_def_id(fn_node_id).index;
let closure_expr_def_id = self.tcx.hir.local_def_id(fn_node_id);
let var_hir_id = self.tcx.hir.node_to_hir_id(var_id);
let upvar_id = ty::UpvarId {
var_id: var_hir_id,
closure_expr_id: closure_expr_def_index
closure_expr_id: closure_expr_def_id.to_local(),
};
let var_ty = self.node_ty(var_hir_id)?;
@ -837,7 +837,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
// The environment of a closure is guaranteed to
// outlive any bindings introduced in the body of the
// closure itself.
scope: DefId::local(upvar_id.closure_expr_id),
scope: upvar_id.closure_expr_id.to_def_id(),
bound_region: ty::BrEnv
}));

View file

@ -769,7 +769,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for TypeckTables<'gcx> {
};
let closure_def_id = DefId {
krate: local_id_root.krate,
index: closure_expr_id,
index: closure_expr_id.to_def_id().index,
};
(hcx.def_path_hash(var_owner_def_id),
var_id.local_id,

View file

@ -17,7 +17,7 @@ pub use self::fold::TypeFoldable;
use hir::{map as hir_map, FreevarMap, TraitMap};
use hir::def::{Def, CtorKind, ExportMap};
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use hir::map::DefPathData;
use ich::StableHashingContext;
use middle::const_val::ConstVal;
@ -573,7 +573,7 @@ impl<T> Slice<T> {
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct UpvarId {
pub var_id: hir::HirId,
pub closure_expr_id: DefIndex,
pub closure_expr_id: LocalDefId,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, Copy)]

View file

@ -29,7 +29,7 @@ use rustc::middle::dataflow::BitwiseOperator;
use rustc::middle::dataflow::DataFlowOperator;
use rustc::middle::dataflow::KillFrom;
use rustc::middle::borrowck::BorrowCheckResult;
use rustc::hir::def_id::{DefId, DefIndex};
use rustc::hir::def_id::{DefId, LocalDefId};
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
use rustc::middle::mem_categorization::Categorization;
@ -376,9 +376,9 @@ pub enum LoanPathElem<'tcx> {
LpInterior(Option<DefId>, InteriorKind),
}
fn closure_to_block(closure_id: DefIndex,
fn closure_to_block(closure_id: LocalDefId,
tcx: TyCtxt) -> ast::NodeId {
let closure_id = tcx.hir.def_index_to_node_id(closure_id);
let closure_id = tcx.hir.local_def_id_to_node_id(closure_id);
match tcx.hir.get(closure_id) {
hir_map::NodeExpr(expr) => match expr.node {
hir::ExprClosure(.., body_id, _, _) => {
@ -1101,7 +1101,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
} else {
"consider changing this closure to take self by mutable reference"
};
let node_id = self.tcx.hir.def_index_to_node_id(id);
let node_id = self.tcx.hir.local_def_id_to_node_id(id);
let help_span = self.tcx.hir.span(node_id);
self.cannot_act_on_capture_in_sharable_fn(span,
prefix,
@ -1297,7 +1297,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
};
if kind == ty::ClosureKind::Fn {
let closure_node_id =
self.tcx.hir.def_index_to_node_id(upvar_id.closure_expr_id);
self.tcx.hir.local_def_id_to_node_id(upvar_id.closure_expr_id);
db.span_help(self.tcx.hir.span(closure_node_id),
"consider changing this closure to take \
self by mutable reference");

View file

@ -13,7 +13,7 @@ use build;
use hair::cx::Cx;
use hair::LintLevel;
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::hir::def_id::{DefId, LocalDefId};
use rustc::middle::region;
use rustc::mir::*;
use rustc::mir::transform::MirSource;
@ -414,10 +414,10 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
freevars.iter().map(|fv| {
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 closure_expr_id = tcx.hir.local_def_id(fn_id);
let capture = hir.tables().upvar_capture(ty::UpvarId {
var_id: var_hir_id,
closure_expr_id,
closure_expr_id: LocalDefId::from_def_id(closure_expr_id),
});
let by_ref = match capture {
ty::UpvarCapture::ByValue => false,

View file

@ -20,6 +20,7 @@ use rustc::ty::{self, AdtKind, VariantDef, Ty};
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
use rustc::ty::cast::CastKind as TyCastKind;
use rustc::hir;
use rustc::hir::def_id::LocalDefId;
impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
type Output = Expr<'tcx>;
@ -783,7 +784,7 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// point we need an implicit deref
let upvar_id = ty::UpvarId {
var_id: var_hir_id,
closure_expr_id: closure_def_id.index,
closure_expr_id: LocalDefId::from_def_id(closure_def_id),
};
match cx.tables().upvar_capture(upvar_id) {
ty::UpvarCapture::ByValue => field_kind,
@ -897,7 +898,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let var_hir_id = cx.tcx.hir.node_to_hir_id(freevar.var_id());
let upvar_id = ty::UpvarId {
var_id: var_hir_id,
closure_expr_id: cx.tcx.hir.local_def_id(closure_expr.id).index,
closure_expr_id: cx.tcx.hir.local_def_id(closure_expr.id).to_local(),
};
let upvar_capture = cx.tables().upvar_capture(upvar_id);
let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);

View file

@ -50,7 +50,7 @@ use rustc::infer::UpvarRegion;
use syntax::ast;
use syntax_pos::Span;
use rustc::hir;
use rustc::hir::def_id::DefIndex;
use rustc::hir::def_id::LocalDefId;
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::util::nodemap::FxHashMap;
@ -128,7 +128,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
for freevar in freevars {
let upvar_id = ty::UpvarId {
var_id: self.tcx.hir.node_to_hir_id(freevar.var_id()),
closure_expr_id: closure_def_id.index,
closure_expr_id: LocalDefId::from_def_id(closure_def_id),
};
debug!("seed upvar_id {:?}", upvar_id);
@ -167,7 +167,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Write the adjusted values back into the main tables.
if infer_kind {
if let Some(kind) = delegate.adjust_closure_kinds
.remove(&closure_def_id.index) {
.remove(&closure_def_id.to_local()) {
self.tables
.borrow_mut()
.closure_kinds_mut()
@ -231,7 +231,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// This may change if abstract return types of some sort are
// implemented.
let tcx = self.tcx;
let closure_def_index = tcx.hir.local_def_id(closure_id).index;
let closure_def_index = tcx.hir.local_def_id(closure_id);
tcx.with_freevars(closure_id, |freevars| {
freevars.iter().map(|freevar| {
@ -240,7 +240,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let freevar_ty = self.node_ty(var_hir_id);
let upvar_id = ty::UpvarId {
var_id: var_hir_id,
closure_expr_id: closure_def_index,
closure_expr_id: LocalDefId::from_def_id(closure_def_index),
};
let capture = self.tables.borrow().upvar_capture(upvar_id);
@ -263,7 +263,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
struct InferBorrowKind<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
adjust_closure_kinds: FxHashMap<DefIndex, (ty::ClosureKind, Option<(Span, ast::Name)>)>,
adjust_closure_kinds: FxHashMap<LocalDefId, (ty::ClosureKind, Option<(Span, ast::Name)>)>,
adjust_upvar_captures: ty::UpvarCaptureMap<'tcx>,
}
@ -481,7 +481,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
}
fn adjust_closure_kind(&mut self,
closure_id: DefIndex,
closure_id: LocalDefId,
new_kind: ty::ClosureKind,
upvar_span: Span,
var_name: ast::Name) {
@ -490,7 +490,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
let closure_kind = self.adjust_closure_kinds.get(&closure_id).cloned()
.or_else(|| {
let closure_id = self.fcx.tcx.hir.def_index_to_hir_id(closure_id);
let closure_id = self.fcx.tcx.hir.local_def_id_to_hir_id(closure_id);
self.fcx.tables.borrow().closure_kinds().get(closure_id).cloned()
});