about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-09-04 13:52:28 -0400
committerNiko Matsakis <niko@alum.mit.edu>2015-10-01 10:37:19 -0400
commit5600c6282e699ad77d0303456fa068aa649b7007 (patch)
treedf54d9d308b9521c27064dbaedbcd1d206ddb612
parentaa40a1cad0f359bfc799545e70bb5c7c9e72ba93 (diff)
downloadrust-5600c6282e699ad77d0303456fa068aa649b7007.tar.gz
rust-5600c6282e699ad77d0303456fa068aa649b7007.zip
move direct accesses of `node` to go through `as_local_node_id`, unless
they are being used as an opaque "position identifier"
-rw-r--r--src/librustc/front/map/mod.rs14
-rw-r--r--src/librustc/metadata/csearch.rs74
-rw-r--r--src/librustc/metadata/decoder.rs50
-rw-r--r--src/librustc/metadata/encoder.rs73
-rw-r--r--src/librustc/metadata/tydecode.rs8
-rw-r--r--src/librustc/metadata/tyencode.rs2
-rw-r--r--src/librustc/middle/astencode.rs6
-rw-r--r--src/librustc/middle/check_static_recursion.rs56
-rw-r--r--src/librustc/middle/const_eval.rs34
-rw-r--r--src/librustc/middle/dead.rs59
-rw-r--r--src/librustc/middle/def_id.rs12
-rw-r--r--src/librustc/middle/lang_items.rs2
-rw-r--r--src/librustc/middle/pat_util.rs4
-rw-r--r--src/librustc/middle/reachable.rs59
-rw-r--r--src/librustc/middle/stability.rs2
-rw-r--r--src/librustc/middle/ty/error.rs20
-rw-r--r--src/librustc/middle/ty/mod.rs30
-rw-r--r--src/librustc/middle/ty/sty.rs2
-rw-r--r--src/librustc/middle/ty/util.rs2
-rw-r--r--src/librustc/util/ppaux.rs20
-rw-r--r--src/librustc_borrowck/borrowck/fragments.rs3
-rw-r--r--src/librustc_driver/test.rs2
-rw-r--r--src/librustc_lint/builtin.rs39
-rw-r--r--src/librustc_lint/unused.rs4
-rw-r--r--src/librustc_mir/tcx/expr.rs2
-rw-r--r--src/librustc_privacy/lib.rs96
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs4
-rw-r--r--src/librustc_resolve/lib.rs18
-rw-r--r--src/librustc_resolve/record_exports.rs6
-rw-r--r--src/librustc_trans/save/mod.rs43
-rw-r--r--src/librustc_trans/save/recorder.rs20
-rw-r--r--src/librustc_trans/trans/base.rs18
-rw-r--r--src/librustc_trans/trans/callee.rs20
-rw-r--r--src/librustc_trans/trans/closure.rs17
-rw-r--r--src/librustc_trans/trans/consts.rs7
-rw-r--r--src/librustc_trans/trans/debuginfo/metadata.rs6
-rw-r--r--src/librustc_trans/trans/debuginfo/utils.rs9
-rw-r--r--src/librustc_trans/trans/expr.rs4
-rw-r--r--src/librustc_trans/trans/inline.rs2
-rw-r--r--src/librustc_trans/trans/monomorphize.rs25
-rw-r--r--src/librustc_typeck/astconv.rs22
-rw-r--r--src/librustc_typeck/check/compare_method.rs8
-rw-r--r--src/librustc_typeck/check/dropck.rs14
-rw-r--r--src/librustc_typeck/check/method/suggest.rs10
-rw-r--r--src/librustc_typeck/check/mod.rs7
-rw-r--r--src/librustc_typeck/check/upvar.rs10
-rw-r--r--src/librustc_typeck/check/writeback.rs4
-rw-r--r--src/librustc_typeck/coherence/mod.rs45
-rw-r--r--src/librustc_typeck/coherence/overlap.rs6
-rw-r--r--src/librustc_typeck/collect.rs93
-rw-r--r--src/librustc_typeck/variance.rs17
-rw-r--r--src/librustdoc/clean/mod.rs11
-rw-r--r--src/librustdoc/core.rs18
-rw-r--r--src/librustdoc/html/format.rs2
-rw-r--r--src/librustdoc/html/render.rs27
-rw-r--r--src/librustdoc/passes.rs39
-rw-r--r--src/librustdoc/visit_ast.rs12
57 files changed, 652 insertions, 567 deletions
diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs
index 8d8932552b7..b8d96cd3ba7 100644
--- a/src/librustc/front/map/mod.rs
+++ b/src/librustc/front/map/mod.rs
@@ -274,7 +274,7 @@ impl<'ast> Map<'ast> {
 
     pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
         if def_id.krate == LOCAL_CRATE {
-            Some(def_id.node)
+            Some(def_id.xxx_node)
         } else {
             None
         }
@@ -301,6 +301,10 @@ impl<'ast> Map<'ast> {
         }
     }
 
+    pub fn get_if_local(&self, id: DefId) -> Option<Node<'ast>> {
+        self.as_local_node_id(id).map(|id| self.get(id))
+    }
+
     /// Retrieve the Node corresponding to `id`, returning None if
     /// cannot be found.
     pub fn find(&self, id: NodeId) -> Option<Node<'ast>> {
@@ -609,9 +613,13 @@ impl<'ast> Map<'ast> {
             .unwrap_or_else(|| panic!("AstMap.span: could not find span for id {:?}", id))
     }
 
+    pub fn span_if_local(&self, id: DefId) -> Option<Span> {
+        self.as_local_node_id(id).map(|id| self.span(id))
+    }
+
     pub fn def_id_span(&self, def_id: DefId, fallback: Span) -> Span {
-        if def_id.is_local() {
-            self.opt_span(def_id.node).unwrap_or(fallback)
+        if let Some(node_id) = self.as_local_node_id(def_id) {
+            self.opt_span(node_id).unwrap_or(fallback)
         } else {
             fallback
         }
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 88d73b3feb3..70a969e4d82 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -33,7 +33,7 @@ pub struct MethodInfo {
 
 pub fn get_symbol(cstore: &cstore::CStore, def: DefId) -> String {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_symbol(&cdata, def.node)
+    decoder::get_symbol(&cdata, def.xxx_node)
 }
 
 /// Iterates over all the language items in the given crate.
@@ -59,7 +59,7 @@ pub fn each_child_of_item<F>(cstore: &cstore::CStore,
     };
     decoder::each_child_of_item(cstore.intr.clone(),
                                 &*crate_data,
-                                def_id.node,
+                                def_id.xxx_node,
                                 get_crate_data,
                                 callback)
 }
@@ -83,7 +83,7 @@ pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
 pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    let path = decoder::get_item_path(&*cdata, def.node);
+    let path = decoder::get_item_path(&*cdata, def.xxx_node);
 
     cdata.with_local_path(|cpath| {
         let mut r = Vec::with_capacity(cpath.len() + path.len());
@@ -96,7 +96,7 @@ pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> {
 pub fn get_item_name(tcx: &ty::ctxt, def: DefId) -> ast::Name {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_item_name(&cstore.intr, &cdata, def.node)
+    decoder::get_item_name(&cstore.intr, &cdata, def.xxx_node)
 }
 
 pub enum FoundAst<'ast> {
@@ -113,14 +113,14 @@ pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId,
                                 -> FoundAst<'tcx> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::maybe_get_item_ast(&*cdata, tcx, def.node, decode_inlined_item)
+    decoder::maybe_get_item_ast(&*cdata, tcx, def.xxx_node, decode_inlined_item)
 }
 
 /// Returns information about the given implementation.
 pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: DefId)
                       -> Vec<ty::ImplOrTraitItemId> {
     let cdata = cstore.get_crate_data(impl_def_id.krate);
-    decoder::get_impl_items(&*cdata, impl_def_id.node)
+    decoder::get_impl_items(&*cdata, impl_def_id.xxx_node)
 }
 
 pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
@@ -128,7 +128,7 @@ pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
     let cdata = tcx.sess.cstore.get_crate_data(def.krate);
     decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(),
                                     &*cdata,
-                                    def.node,
+                                    def.xxx_node,
                                     tcx)
 }
 
@@ -136,24 +136,24 @@ pub fn get_trait_name(cstore: &cstore::CStore, def: DefId) -> ast::Name {
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_trait_name(cstore.intr.clone(),
                             &*cdata,
-                            def.node)
+                            def.xxx_node)
 }
 
 pub fn is_static_method(cstore: &cstore::CStore, def: DefId) -> bool {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::is_static_method(&*cdata, def.node)
+    decoder::is_static_method(&*cdata, def.xxx_node)
 }
 
 pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: DefId)
                               -> Vec<ty::ImplOrTraitItemId> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_item_def_ids(&*cdata, def.node)
+    decoder::get_trait_item_def_ids(&*cdata, def.xxx_node)
 }
 
 pub fn get_item_variances(cstore: &cstore::CStore,
                           def: DefId) -> ty::ItemVariances {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_item_variances(&*cdata, def.node)
+    decoder::get_item_variances(&*cdata, def.xxx_node)
 }
 
 pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
@@ -161,39 +161,39 @@ pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
                                         -> Vec<Rc<ty::Method<'tcx>>> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx)
+    decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.xxx_node, tcx)
 }
 
 pub fn get_associated_consts<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
                                    -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.node, tcx)
+    decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.xxx_node, tcx)
 }
 
 pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: DefId)
                           -> Option<ast::Name> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_type_name_if_impl(&*cdata, def.node)
+    decoder::get_type_name_if_impl(&*cdata, def.xxx_node)
 }
 
 pub fn get_methods_if_impl(cstore: &cstore::CStore,
                                   def: DefId)
                                -> Option<Vec<MethodInfo> > {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.node)
+    decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.xxx_node)
 }
 
 pub fn get_item_attrs(cstore: &cstore::CStore,
                       def_id: DefId)
                       -> Vec<ast::Attribute> {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_item_attrs(&*cdata, def_id.node)
+    decoder::get_item_attrs(&*cdata, def_id.xxx_node)
 }
 
 pub fn get_struct_field_names(cstore: &cstore::CStore, def: DefId) -> Vec<ast::Name> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_struct_field_names(&cstore.intr, &*cdata, def.node)
+    decoder::get_struct_field_names(&cstore.intr, &*cdata, def.xxx_node)
 }
 
 pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId) -> FnvHashMap<ast::NodeId,
@@ -207,19 +207,19 @@ pub fn get_type<'tcx>(tcx: &ty::ctxt<'tcx>,
                       -> ty::TypeScheme<'tcx> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_type(&*cdata, def.node, tcx)
+    decoder::get_type(&*cdata, def.xxx_node, tcx)
 }
 
 pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::TraitDef<'tcx> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_def(&*cdata, def.node, tcx)
+    decoder::get_trait_def(&*cdata, def.xxx_node, tcx)
 }
 
 pub fn get_adt_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_adt_def(&cstore.intr, &*cdata, def.node, tcx)
+    decoder::get_adt_def(&cstore.intr, &*cdata, def.xxx_node, tcx)
 }
 
 pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
@@ -227,7 +227,7 @@ pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
 {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_predicates(&*cdata, def.node, tcx)
+    decoder::get_predicates(&*cdata, def.xxx_node, tcx)
 }
 
 pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
@@ -235,7 +235,7 @@ pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
 {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_super_predicates(&*cdata, def.node, tcx)
+    decoder::get_super_predicates(&*cdata, def.xxx_node, tcx)
 }
 
 pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
@@ -244,7 +244,7 @@ pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
 {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_impl_polarity(&*cdata, def.node)
+    decoder::get_impl_polarity(&*cdata, def.xxx_node)
 }
 
 pub fn get_custom_coerce_unsized_kind<'tcx>(
@@ -254,7 +254,7 @@ pub fn get_custom_coerce_unsized_kind<'tcx>(
 {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_custom_coerce_unsized_kind(&*cdata, def.node)
+    decoder::get_custom_coerce_unsized_kind(&*cdata, def.xxx_node)
 }
 
 // Given a def_id for an impl, return the trait it implements,
@@ -264,7 +264,7 @@ pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
                             -> Option<ty::TraitRef<'tcx>> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_impl_trait(&*cdata, def.node, tcx)
+    decoder::get_impl_trait(&*cdata, def.xxx_node, tcx)
 }
 
 pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
@@ -279,7 +279,7 @@ pub fn each_inherent_implementation_for_type<F>(cstore: &cstore::CStore,
     F: FnMut(DefId),
 {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::each_inherent_implementation_for_type(&*cdata, def_id.node, callback)
+    decoder::each_inherent_implementation_for_type(&*cdata, def_id.xxx_node, callback)
 }
 
 pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
@@ -300,7 +300,7 @@ pub fn get_trait_of_item(cstore: &cstore::CStore,
                          tcx: &ty::ctxt)
                          -> Option<DefId> {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_trait_of_item(&*cdata, def_id.node, tcx)
+    decoder::get_trait_of_item(&*cdata, def_id.xxx_node, tcx)
 }
 
 pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
@@ -308,7 +308,7 @@ pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
     -> Option<DefId>
 {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.node)
+    decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.xxx_node)
 }
 
 pub fn get_dylib_dependency_formats(cstore: &cstore::CStore,
@@ -330,7 +330,7 @@ pub fn get_method_arg_names(cstore: &cstore::CStore, did: DefId)
     -> Vec<String>
 {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::get_method_arg_names(&*cdata, did.node)
+    decoder::get_method_arg_names(&*cdata, did.xxx_node)
 }
 
 pub fn get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum)
@@ -342,24 +342,24 @@ pub fn get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum)
 
 pub fn is_typedef(cstore: &cstore::CStore, did: DefId) -> bool {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_typedef(&*cdata, did.node)
+    decoder::is_typedef(&*cdata, did.xxx_node)
 }
 
 pub fn is_const_fn(cstore: &cstore::CStore, did: DefId) -> bool {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_const_fn(&*cdata, did.node)
+    decoder::is_const_fn(&*cdata, did.xxx_node)
 }
 
 pub fn is_impl(cstore: &cstore::CStore, did: DefId) -> bool {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_impl(&*cdata, did.node)
+    decoder::is_impl(&*cdata, did.xxx_node)
 }
 
 pub fn get_stability(cstore: &cstore::CStore,
                      def: DefId)
                      -> Option<attr::Stability> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_stability(&*cdata, def.node)
+    decoder::get_stability(&*cdata, def.xxx_node)
 }
 
 pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool {
@@ -369,21 +369,21 @@ pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool {
 pub fn get_repr_attrs(cstore: &cstore::CStore, def: DefId)
                       -> Vec<attr::ReprAttr> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_repr_attrs(&*cdata, def.node)
+    decoder::get_repr_attrs(&*cdata, def.xxx_node)
 }
 
 pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: DefId) -> bool {
     let cdata = cstore.get_crate_data(trait_def_id.krate);
-    decoder::is_defaulted_trait(&*cdata, trait_def_id.node)
+    decoder::is_defaulted_trait(&*cdata, trait_def_id.xxx_node)
 }
 
 pub fn is_default_impl(cstore: &cstore::CStore, impl_did: DefId) -> bool {
     let cdata = cstore.get_crate_data(impl_did.krate);
-    decoder::is_default_impl(&*cdata, impl_did.node)
+    decoder::is_default_impl(&*cdata, impl_did.xxx_node)
 }
 
 pub fn is_extern_fn(cstore: &cstore::CStore, did: DefId,
                     tcx: &ty::ctxt) -> bool {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_extern_fn(&*cdata, did.node, tcx)
+    decoder::is_extern_fn(&*cdata, did.xxx_node, tcx)
 }
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 2e7a49b25fe..54a815b454a 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -170,7 +170,7 @@ fn item_symbol(item: rbml::Doc) -> String {
 
 fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
     let id = reader::doc_as_u64(d);
-    let def_id = DefId { krate: (id >> 32) as u32, node: id as u32 };
+    let def_id = DefId { krate: (id >> 32) as u32, xxx_node: id as u32 };
     translate_def_id(cdata, def_id)
 }
 
@@ -378,7 +378,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
         let mut disr_val = 0;
         reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| {
             let did = translated_def_id(cdata, p);
-            let item = cdata.lookup_item(did.node);
+            let item = cdata.lookup_item(did.xxx_node);
 
             if let Some(disr) = variant_disr_val(item) {
                 disr_val = disr;
@@ -428,7 +428,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
     }
 
     let doc = cdata.lookup_item(item_id);
-    let did = DefId { krate: cdata.cnum, node: item_id };
+    let did = DefId { krate: cdata.cnum, xxx_node: item_id };
     let (kind, variants) = match item_family(doc) {
         Enum => (ty::AdtKind::Enum,
                  get_enum_variants(intr, cdata, doc, tcx)),
@@ -448,7 +448,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
             // from the ctor.
             debug!("evaluating the ctor-type of {:?}",
                    variant.name);
-            let ctor_ty = get_type(cdata, variant.did.node, tcx).ty;
+            let ctor_ty = get_type(cdata, variant.did.xxx_node, tcx).ty;
             debug!("evaluating the ctor-type of {:?}.. {:?}",
                    variant.name,
                    ctor_ty);
@@ -468,7 +468,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
         } else {
             for field in &variant.fields {
                 debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
-                let ty = get_type(cdata, field.did.node, tcx).ty;
+                let ty = get_type(cdata, field.did.xxx_node, tcx).ty;
                 field.fulfill_ty(ty);
                 debug!("evaluating the type of {:?}::{:?}: {:?}",
                        variant.name, field.name, ty);
@@ -501,7 +501,7 @@ pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
                       -> ty::TypeScheme<'tcx>
 {
     let item_doc = cdata.lookup_item(id);
-    let t = item_type(DefId { krate: cdata.cnum, node: id }, item_doc, tcx,
+    let t = item_type(DefId { krate: cdata.cnum, xxx_node: id }, item_doc, tcx,
                       cdata);
     let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
     ty::TypeScheme {
@@ -634,7 +634,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
         };
 
         // Get the item.
-        match crate_data.get_item(child_def_id.node) {
+        match crate_data.get_item(child_def_id.xxx_node) {
             None => {}
             Some(child_item_doc) => {
                 // Hand off the item to the callback.
@@ -652,12 +652,12 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
     for inherent_impl_def_id_doc in reader::tagged_docs(item_doc,
                                                              tag_items_data_item_inherent_impl) {
         let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata);
-        if let Some(inherent_impl_doc) = cdata.get_item(inherent_impl_def_id.node) {
+        if let Some(inherent_impl_doc) = cdata.get_item(inherent_impl_def_id.xxx_node) {
             for impl_item_def_id_doc in reader::tagged_docs(inherent_impl_doc,
                                                                  tag_item_impl_item) {
                 let impl_item_def_id = item_def_id(impl_item_def_id_doc,
                                                    cdata);
-                if let Some(impl_method_doc) = cdata.get_item(impl_item_def_id.node) {
+                if let Some(impl_method_doc) = cdata.get_item(impl_item_def_id.xxx_node) {
                     if let StaticMethod = item_family(impl_method_doc) {
                         // Hand off the static method to the callback.
                         let static_method_name = item_name(&*intr, impl_method_doc);
@@ -693,7 +693,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
         };
 
         // Get the item.
-        if let Some(child_item_doc) = crate_data.get_item(child_def_id.node) {
+        if let Some(child_item_doc) = crate_data.get_item(child_def_id.xxx_node) {
             // Hand off the item to the callback.
             let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
             // These items have a public visibility because they're part of
@@ -771,7 +771,7 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI
         Err(path) => {
             match item_parent_item(cdata, item_doc) {
                 Some(did) => {
-                    let parent_item = cdata.lookup_item(did.node);
+                    let parent_item = cdata.lookup_item(did.xxx_node);
                     match decode_inlined_item(cdata, tcx, path, parent_item) {
                         Ok(ii) => csearch::FoundAst::FoundParent(did, ii),
                         Err(_) => csearch::FoundAst::NotFound
@@ -852,7 +852,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
     let def_id = item_def_id(item_doc, cdata);
 
     let container_id = item_require_parent_item(cdata, item_doc);
-    let container_doc = cdata.lookup_item(container_id.node);
+    let container_doc = cdata.lookup_item(container_id.xxx_node);
     let container = match item_family(container_doc) {
         Trait => TraitContainer(container_id),
         _ => ImplContainer(container_id),
@@ -932,12 +932,12 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
 
     reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| {
         let did = item_def_id(mth_id, cdata);
-        let mth = cdata.lookup_item(did.node);
+        let mth = cdata.lookup_item(did.xxx_node);
 
         if item_sort(mth) == Some('p') {
             let trait_item = get_impl_or_trait_item(intr.clone(),
                                                     cdata,
-                                                    did.node,
+                                                    did.xxx_node,
                                                     tcx);
             if let ty::MethodTraitItem(ref method) = trait_item {
                 Some((*method).clone())
@@ -960,13 +960,13 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
     [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| {
         reader::tagged_docs(item, tag).filter_map(|ac_id| {
             let did = item_def_id(ac_id, cdata);
-            let ac_doc = cdata.lookup_item(did.node);
+            let ac_doc = cdata.lookup_item(did.xxx_node);
 
             match item_sort(ac_doc) {
                 Some('C') | Some('c') => {
                     let trait_item = get_impl_or_trait_item(intr.clone(),
                                                             cdata,
-                                                            did.node,
+                                                            did.xxx_node,
                                                             tcx);
                     if let ty::ConstTraitItem(ref ac) = trait_item {
                         Some((*ac).clone())
@@ -1011,7 +1011,7 @@ pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
 
     let mut impl_methods = Vec::new();
     for impl_method_id in impl_method_ids {
-        let impl_method_doc = cdata.lookup_item(impl_method_id.node);
+        let impl_method_doc = cdata.lookup_item(impl_method_id.xxx_node);
         let family = item_family(impl_method_doc);
         match family {
             StaticMethod | Method => {
@@ -1047,7 +1047,7 @@ pub fn get_item_attrs(cdata: Cmd,
     // we assume that someone passing in a tuple struct ctor is actually wanting to
     // look at the definition
     let node_id = get_tuple_struct_definition_if_ctor(cdata, orig_node_id);
-    let node_id = node_id.map(|x| x.node).unwrap_or(orig_node_id);
+    let node_id = node_id.map(|x| x.xxx_node).unwrap_or(orig_node_id);
     let item = cdata.lookup_item(node_id);
     get_attributes(item)
 }
@@ -1228,14 +1228,14 @@ pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()>
 // crate to the correct local crate number.
 pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
     if did.is_local() {
-        return DefId { krate: cdata.cnum, node: did.node };
+        return DefId { krate: cdata.cnum, xxx_node: did.xxx_node };
     }
 
     match cdata.cnum_map.borrow().get(&did.krate) {
         Some(&n) => {
             DefId {
                 krate: n,
-                node: did.node,
+                xxx_node: did.xxx_node,
             }
         }
         None => panic!("didn't find a crate in the cnum_map")
@@ -1246,12 +1246,12 @@ pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
 // for an external crate.
 fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
     if did.krate == cdata.cnum {
-        return Some(DefId { krate: LOCAL_CRATE, node: did.node });
+        return Some(DefId { krate: LOCAL_CRATE, xxx_node: did.xxx_node });
     }
 
     for (&local, &global) in cdata.cnum_map.borrow().iter() {
         if global == did.krate {
-            return Some(DefId { krate: local, node: did.node });
+            return Some(DefId { krate: local, xxx_node: did.xxx_node });
         }
     }
 
@@ -1277,7 +1277,7 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd,
     F: FnMut(DefId),
 {
     if cdata.cnum == def_id.krate {
-        let item_doc = cdata.lookup_item(def_id.node);
+        let item_doc = cdata.lookup_item(def_id.xxx_node);
         for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_extension_impl) {
             callback(item_def_id(impl_doc, cdata));
         }
@@ -1306,7 +1306,7 @@ pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
         None => return None,
         Some(item_id) => item_id,
     };
-    let parent_item_doc = cdata.lookup_item(parent_item_id.node);
+    let parent_item_doc = cdata.lookup_item(parent_item_id.xxx_node);
     match item_family(parent_item_doc) {
         Trait => Some(item_def_id(parent_item_doc, cdata)),
         Impl | DefaultImpl => {
@@ -1404,7 +1404,7 @@ pub fn get_reachable_ids(cdata: Cmd) -> Vec<DefId> {
     reader::tagged_docs(items, tag_reachable_id).map(|doc| {
         DefId {
             krate: cdata.cnum,
-            node: reader::doc_as_u32(doc),
+            xxx_node: reader::doc_as_u32(doc),
         }
     }).collect()
 }
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index b67da4baf5a..14e5e8b41ff 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -75,6 +75,12 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
     pub reachable: &'a NodeSet,
 }
 
+impl<'a, 'tcx> EncodeContext<'a,'tcx> {
+    fn local_id(&self, def_id: DefId) -> NodeId {
+        self.tcx.map.as_local_node_id(def_id).unwrap()
+    }
+}
+
 fn encode_name(rbml_w: &mut Encoder, name: Name) {
     rbml_w.wr_tagged_str(tag_paths_data_name, &name.as_str());
 }
@@ -109,11 +115,11 @@ fn encode_family(rbml_w: &mut Encoder, c: char) {
 }
 
 pub fn def_to_u64(did: DefId) -> u64 {
-    (did.krate as u64) << 32 | (did.node as u64)
+    (did.krate as u64) << 32 | (did.xxx_node as u64)
 }
 
 pub fn def_to_string(did: DefId) -> String {
-    format!("{}:{}", did.krate, did.node)
+    format!("{}:{}", did.krate, did.xxx_node)
 }
 
 fn encode_item_variances(rbml_w: &mut Encoder,
@@ -281,7 +287,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
     let def = ecx.tcx.lookup_adt_def(ecx.tcx.map.local_def_id(id));
     for variant in &def.variants {
         let vid = variant.did;
-        assert!(vid.is_local());
+        let variant_node_id = ecx.local_id(vid);
 
         if let ty::VariantKind::Dict = variant.kind() {
             // tuple-like enum variant fields aren't really items so
@@ -292,7 +298,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
         }
 
         index.push(IndexEntry {
-            node: vid.node,
+            node: vid.xxx_node,
             pos: rbml_w.mark_stable_position(),
         });
         rbml_w.start_tag(tag_items_data_item);
@@ -319,9 +325,9 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
             encode_disr_val(ecx, rbml_w, specified_disr_val);
             disr_val = specified_disr_val;
         }
-        encode_bounds_and_type_for_item(rbml_w, ecx, vid.node);
+        encode_bounds_and_type_for_item(rbml_w, ecx, variant_node_id);
 
-        ecx.tcx.map.with_path(vid.node, |path| encode_path(rbml_w, path));
+        ecx.tcx.map.with_path(variant_node_id, |path| encode_path(rbml_w, path));
         rbml_w.end_tag();
         disr_val = disr_val.wrapping_add(1);
     }
@@ -405,8 +411,21 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
                                     rbml_w: &mut Encoder,
                                     mod_path: PathElems,
                                     exp: &def::Export) {
-    if let Some(ast_map::NodeItem(item)) = ecx.tcx.map.find(exp.def_id.node) {
-        let path_differs = ecx.tcx.map.with_path(exp.def_id.node, |path| {
+    let exp_node_id = if let Some(n) = ecx.tcx.map.as_local_node_id(exp.def_id) {
+        n
+    } else {
+        // Before the refactor that introducd `as_local_node_id`, we
+        // were just extracting the node and checking into the
+        // ast-map. Since the node might have been from another crate,
+        // this was a tenuous thing to do at best. Anyway, I'm not
+        // 100% clear on why it's ok to ignore things from other
+        // crates, but it seems to be what we were doing pre-refactor.
+        // -nmatsakis
+        return;
+    };
+
+    if let Some(ast_map::NodeItem(item)) = ecx.tcx.map.find(exp_node_id) {
+        let path_differs = ecx.tcx.map.with_path(exp_node_id, |path| {
             let (mut a, mut b) = (path, mod_path.clone());
             loop {
                 match (a.next(), b.next()) {
@@ -476,11 +495,10 @@ fn encode_reexports(ecx: &EncodeContext,
         Some(exports) => {
             debug!("(encoding info for module) found reexports for {}", id);
             for exp in exports {
-                debug!("(encoding info for module) reexport '{}' ({}/{}) for \
+                debug!("(encoding info for module) reexport '{}' ({:?}) for \
                         {}",
                        exp.name,
-                       exp.def_id.krate,
-                       exp.def_id.node,
+                       exp.def_id,
                        id);
                 rbml_w.start_tag(tag_items_data_item_reexport);
                 rbml_w.wr_tagged_u64(tag_items_data_item_reexport_def_id,
@@ -615,7 +633,7 @@ fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                           field: ty::FieldDef<'tcx>,
                           global_index: &mut Vec<IndexEntry>) {
     let nm = field.name;
-    let id = field.did.node;
+    let id = ecx.local_id(field.did);
 
     let pos = rbml_w.mark_stable_position();
     global_index.push(IndexEntry {
@@ -792,7 +810,7 @@ fn encode_info_for_associated_const(ecx: &EncodeContext,
     encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(parent_id));
     encode_item_sort(rbml_w, 'C');
 
-    encode_bounds_and_type_for_item(rbml_w, ecx, associated_const.def_id.local_id());
+    encode_bounds_and_type_for_item(rbml_w, ecx, ecx.local_id(associated_const.def_id));
 
     let stab = stability::lookup(ecx.tcx, associated_const.def_id);
     encode_stability(rbml_w, stab);
@@ -831,7 +849,8 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
     encode_stability(rbml_w, stab);
 
     // The type for methods gets encoded twice, which is unfortunate.
-    encode_bounds_and_type_for_item(rbml_w, ecx, m.def_id.local_id());
+    let m_node_id = ecx.local_id(m.def_id);
+    encode_bounds_and_type_for_item(rbml_w, ecx, m_node_id);
 
     let elem = ast_map::PathName(m.name);
     encode_path(rbml_w, impl_path.chain(Some(elem)));
@@ -850,7 +869,8 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
             }
             encode_constness(rbml_w, sig.constness);
             if !any_types {
-                encode_symbol(ecx, rbml_w, m.def_id.node);
+                let m_id = ecx.local_id(m.def_id);
+                encode_symbol(ecx, rbml_w, m_id);
             }
             encode_method_argument_names(rbml_w, &sig.decl);
         }
@@ -1166,7 +1186,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         match struct_def.ctor_id {
             Some(ctor_id) => {
                 encode_info_for_struct_ctor(ecx, rbml_w, item.name,
-                                            ctor_id, index, def_id.node);
+                                            ctor_id, index, item.id);
             }
             None => {}
         }
@@ -1253,7 +1273,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
             };
 
             index.push(IndexEntry {
-                node: trait_item_def_id.def_id().node,
+                node: trait_item_def_id.def_id().xxx_node,
                 pos: rbml_w.mark_stable_position(),
             });
 
@@ -1344,7 +1364,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
             assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE);
 
             index.push(IndexEntry {
-                node: item_def_id.def_id().node,
+                node: item_def_id.def_id().xxx_node,
                 pos: rbml_w.mark_stable_position(),
             });
 
@@ -1370,8 +1390,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
 
                     encode_family(rbml_w, 'C');
 
-                    encode_bounds_and_type_for_item(rbml_w, ecx,
-                                                    associated_const.def_id.local_id());
+                    encode_bounds_and_type_for_item(rbml_w,
+                                                    ecx,
+                                                    ecx.local_id(associated_const.def_id));
 
                     is_nonstatic_method = false;
                 }
@@ -1394,7 +1415,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
                                           METHOD_FAMILY);
                         }
                     }
-                    encode_bounds_and_type_for_item(rbml_w, ecx, method_def_id.local_id());
+                    encode_bounds_and_type_for_item(rbml_w, ecx, ecx.local_id(method_def_id));
 
                     is_nonstatic_method = method_ty.explicit_self !=
                         ty::StaticExplicitSelfCategory;
@@ -1439,8 +1460,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
                     if is_nonstatic_method {
                         // FIXME: I feel like there is something funny
                         // going on.
-                        encode_bounds_and_type_for_item(rbml_w, ecx,
-                            item_def_id.def_id().local_id());
+                        encode_bounds_and_type_for_item(
+                            rbml_w,
+                            ecx,
+                            ecx.local_id(item_def_id.def_id()));
                     }
 
                     if body.is_some() {
@@ -1716,10 +1739,10 @@ fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) {
 
     for (i, &def_id) in ecx.tcx.lang_items.items() {
         if let Some(id) = def_id {
-            if id.is_local() {
+            if let Some(id) = ecx.tcx.map.as_local_node_id(id) {
                 rbml_w.start_tag(tag_lang_items_item);
                 rbml_w.wr_tagged_u32(tag_lang_items_item_id, i as u32);
-                rbml_w.wr_tagged_u32(tag_lang_items_item_node_id, id.node as u32);
+                rbml_w.wr_tagged_u32(tag_lang_items_item_node_id, id as u32);
                 rbml_w.end_tag();
             }
         }
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 75afe11839c..f023049d78f 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -209,10 +209,6 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
             }
             'B' => {
                 assert_eq!(self.next(), '[');
-                // this is the wrong NodeId, but `param_id` is only accessed
-                // by the receiver-matching code in collect, which won't
-                // be going down this code path, and anyway I will kill it
-                // the moment wfcheck becomes the standard.
                 let def_id = self.parse_def(NominalType);
                 let space = self.parse_param_space();
                 assert_eq!(self.next(), '|');
@@ -220,7 +216,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
                 assert_eq!(self.next(), '|');
                 let name = token::intern(&self.parse_str(']'));
                 ty::ReEarlyBound(ty::EarlyBoundRegion {
-                    param_id: def_id,
+                    def_id: def_id,
                     space: space,
                     index: index,
                     name: name
@@ -739,7 +735,7 @@ fn parse_defid(buf: &[u8]) -> DefId {
         None => panic!("internal error: parse_defid: id expected, found {:?}",
                        def_part)
     };
-    DefId { krate: crate_num, node: def_num }
+    DefId { krate: crate_num, xxx_node: def_num }
 }
 
 fn parse_unsafety(c: char) -> hir::Unsafety {
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index c085f0e5825..01e6e30b53f 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -250,7 +250,7 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
         }
         ty::ReEarlyBound(ref data) => {
             mywrite!(w, "B[{}|{}|{}|{}]",
-                     (cx.ds)(data.param_id),
+                     (cx.ds)(data.def_id),
                      data.space.to_uint(),
                      data.index,
                      data.name);
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index a137d295bd1..a06a6b2509a 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -229,7 +229,7 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
     /// refer to the current crate and to the new, inlined node-id.
     pub fn tr_intern_def_id(&self, did: DefId) -> DefId {
         assert_eq!(did.krate, LOCAL_CRATE);
-        DefId { krate: LOCAL_CRATE, node: self.tr_id(did.node) }
+        DefId { krate: LOCAL_CRATE, xxx_node: self.tr_id(did.xxx_node) }
     }
 
     /// Translates a `Span` from an extern crate to the corresponding `Span`
@@ -951,7 +951,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         }
     }
 
-    let lid = DefId { krate: LOCAL_CRATE, node: id };
+    let lid = tcx.map.local_def_id(id);
     if let Some(type_scheme) = tcx.tcache.borrow().get(&lid) {
         rbml_w.tag(c::tag_table_tcache, |rbml_w| {
             rbml_w.id(id);
@@ -1453,7 +1453,7 @@ fn decode_side_tables(dcx: &DecodeContext,
                     }
                     c::tag_table_tcache => {
                         let type_scheme = val_dsr.read_type_scheme(dcx);
-                        let lid = DefId { krate: LOCAL_CRATE, node: id };
+                        let lid = dcx.tcx.map.local_def_id(id);
                         dcx.tcx.register_item_type(lid, type_scheme);
                     }
                     c::tag_table_param_defs => {
diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs
index 942d8313ec2..acb66b8efe7 100644
--- a/src/librustc/middle/check_static_recursion.rs
+++ b/src/librustc/middle/check_static_recursion.rs
@@ -240,37 +240,43 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
                 match self.def_map.borrow().get(&e.id).map(|d| d.base_def) {
                     Some(DefStatic(def_id, _)) |
                     Some(DefAssociatedConst(def_id)) |
-                    Some(DefConst(def_id)) if def_id.is_local() => {
-                        match self.ast_map.get(def_id.node) {
-                          ast_map::NodeItem(item) =>
-                            self.visit_item(item),
-                          ast_map::NodeTraitItem(item) =>
-                            self.visit_trait_item(item),
-                          ast_map::NodeImplItem(item) =>
-                            self.visit_impl_item(item),
-                          ast_map::NodeForeignItem(_) => {},
-                          _ => {
-                              self.sess.span_bug(
-                                  e.span,
-                                  &format!("expected item, found {}",
-                                           self.ast_map.node_to_string(def_id.node)));
-                          }
+                    Some(DefConst(def_id)) => {
+                        if let Some(node_id) = self.ast_map.as_local_node_id(def_id) {
+                            match self.ast_map.get(node_id) {
+                                ast_map::NodeItem(item) =>
+                                    self.visit_item(item),
+                                ast_map::NodeTraitItem(item) =>
+                                    self.visit_trait_item(item),
+                                ast_map::NodeImplItem(item) =>
+                                    self.visit_impl_item(item),
+                                ast_map::NodeForeignItem(_) => {},
+                                _ => {
+                                    self.sess.span_bug(
+                                        e.span,
+                                        &format!("expected item, found {}",
+                                                 self.ast_map.node_to_string(node_id)));
+                                }
+                            }
                         }
                     }
                     // For variants, we only want to check expressions that
                     // affect the specific variant used, but we need to check
                     // the whole enum definition to see what expression that
                     // might be (if any).
-                    Some(DefVariant(enum_id, variant_id, false)) if enum_id.is_local() => {
-                        if let hir::ItemEnum(ref enum_def, ref generics) =
-                               self.ast_map.expect_item(enum_id.local_id()).node {
-                            self.populate_enum_discriminants(enum_def);
-                            let variant = self.ast_map.expect_variant(variant_id.local_id());
-                            self.visit_variant(variant, generics);
-                        } else {
-                            self.sess.span_bug(e.span,
-                                "`check_static_recursion` found \
-                                 non-enum in DefVariant");
+                    Some(DefVariant(enum_id, variant_id, false)) => {
+                        if let Some(enum_node_id) = self.ast_map.as_local_node_id(enum_id) {
+                            if let hir::ItemEnum(ref enum_def, ref generics) =
+                                self.ast_map.expect_item(enum_node_id).node
+                            {
+                                self.populate_enum_discriminants(enum_def);
+                                let variant_id = self.ast_map.as_local_node_id(variant_id).unwrap();
+                                let variant = self.ast_map.expect_variant(variant_id);
+                                self.visit_variant(variant, generics);
+                            } else {
+                                self.sess.span_bug(e.span,
+                                                   "`check_static_recursion` found \
+                                                    non-enum in DefVariant");
+                            }
                         }
                     }
                     _ => ()
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index bde81090aa0..00cfbf2dfe2 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -69,12 +69,13 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
         None
     }
 
-    if enum_def.is_local() {
-        match tcx.map.find(enum_def.node) {
+    if let Some(enum_node_id) = tcx.map.as_local_node_id(enum_def) {
+        let variant_node_id = tcx.map.as_local_node_id(variant_def).unwrap();
+        match tcx.map.find(enum_node_id) {
             None => None,
             Some(ast_map::NodeItem(it)) => match it.node {
                 hir::ItemEnum(hir::EnumDef { ref variants }, _) => {
-                    variant_expr(&variants[..], variant_def.node)
+                    variant_expr(&variants[..], variant_node_id)
                 }
                 _ => None
             },
@@ -88,8 +89,11 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
             }
             None => {}
         }
-        let expr_id = match csearch::maybe_get_item_ast(tcx, enum_def,
-            Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
+        let expr_id = match
+            csearch::maybe_get_item_ast(
+                tcx, enum_def,
+                Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d)))
+        {
             csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
                 hir::ItemEnum(hir::EnumDef { .. }, _) => {
                     tcx.sess.span_bug(
@@ -111,8 +115,8 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
                                         def_id: DefId,
                                         maybe_ref_id: Option<ast::NodeId>)
                                         -> Option<&'tcx Expr> {
-    if def_id.is_local() {
-        match tcx.map.find(def_id.node) {
+    if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
+        match tcx.map.find(node_id) {
             None => None,
             Some(ast_map::NodeItem(it)) => match it.node {
                 hir::ItemConst(_, ref const_expr) => {
@@ -233,14 +237,14 @@ fn inline_const_fn_from_external_crate(tcx: &ty::ctxt, def_id: DefId)
 pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId)
                                    -> Option<FnLikeNode<'tcx>>
 {
-    let fn_id = if !def_id.is_local() {
+    let fn_id = if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
+        node_id
+    } else {
         if let Some(fn_id) = inline_const_fn_from_external_crate(tcx, def_id) {
             fn_id
         } else {
             return None;
         }
-    } else {
-        def_id.node
     };
 
     let fn_like = match FnLikeNode::from_node(tcx.map.get(fn_id)) {
@@ -919,8 +923,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
           let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
           let (const_expr, const_ty) = match opt_def {
               Some(def::DefConst(def_id)) => {
-                  if def_id.is_local() {
-                      match tcx.map.find(def_id.node) {
+                  if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
+                      match tcx.map.find(node_id) {
                           Some(ast_map::NodeItem(it)) => match it.node {
                               hir::ItemConst(ref ty, ref expr) => {
                                   (Some(&**expr), Some(&**ty))
@@ -934,9 +938,9 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                   }
               }
               Some(def::DefAssociatedConst(def_id)) => {
-                  if def_id.is_local() {
+                  if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
                       match tcx.impl_or_trait_item(def_id).container() {
-                          ty::TraitContainer(trait_id) => match tcx.map.find(def_id.node) {
+                          ty::TraitContainer(trait_id) => match tcx.map.find(node_id) {
                               Some(ast_map::NodeTraitItem(ti)) => match ti.node {
                                   hir::ConstTraitItem(ref ty, _) => {
                                       if let ExprTypeChecked = ty_hint {
@@ -954,7 +958,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
                               },
                               _ => (None, None)
                           },
-                          ty::ImplContainer(_) => match tcx.map.find(def_id.node) {
+                          ty::ImplContainer(_) => match tcx.map.find(node_id) {
                               Some(ast_map::NodeImplItem(ii)) => match ii.node {
                                   hir::ConstImplItem(ref ty, ref expr) => {
                                       (Some(&**expr), Some(&**ty))
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 86dbbb578ff..994311efe79 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -29,17 +29,15 @@ use syntax::attr::{self, AttrMetaMethods};
 // explored. For example, if it's a live NodeItem that is a
 // function, then we should explore its block to check for codes that
 // may need to be marked as live.
-fn should_explore(tcx: &ty::ctxt, def_id: DefId) -> bool {
-    if !def_id.is_local() {
-        return false;
-    }
-
-    match tcx.map.find(def_id.node) {
-        Some(ast_map::NodeItem(..))
-        | Some(ast_map::NodeImplItem(..))
-        | Some(ast_map::NodeForeignItem(..))
-        | Some(ast_map::NodeTraitItem(..)) => true,
-        _ => false
+fn should_explore(tcx: &ty::ctxt, node_id: ast::NodeId) -> bool {
+    match tcx.map.find(node_id) {
+        Some(ast_map::NodeItem(..)) |
+        Some(ast_map::NodeImplItem(..)) |
+        Some(ast_map::NodeForeignItem(..)) |
+        Some(ast_map::NodeTraitItem(..)) =>
+            true,
+        _ =>
+            false
     }
 }
 
@@ -50,7 +48,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     struct_has_extern_repr: bool,
     ignore_non_const_paths: bool,
     inherited_pub_visibility: bool,
-    ignore_variant_stack: Vec<ast::NodeId>,
+    ignore_variant_stack: Vec<DefId>,
 }
 
 impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
@@ -68,10 +66,19 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
     }
 
     fn check_def_id(&mut self, def_id: DefId) {
-        if should_explore(self.tcx, def_id) {
-            self.worklist.push(def_id.node);
+        if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
+            if should_explore(self.tcx, node_id) {
+                self.worklist.push(node_id);
+            }
+            self.live_symbols.insert(node_id);
+        }
+    }
+
+    fn insert_def_id(&mut self, def_id: DefId) {
+        if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
+            debug_assert!(!should_explore(self.tcx, node_id));
+            self.live_symbols.insert(node_id);
         }
-        self.live_symbols.insert(def_id.node);
     }
 
     fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
@@ -94,7 +101,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                 def::DefPrimTy(_) => (),
                 def::DefVariant(enum_id, variant_id, _) => {
                     self.check_def_id(enum_id);
-                    if !self.ignore_variant_stack.contains(&variant_id.node) {
+                    if !self.ignore_variant_stack.contains(&variant_id) {
                         self.check_def_id(variant_id);
                     }
                 }
@@ -113,7 +120,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
     fn handle_field_access(&mut self, lhs: &hir::Expr, name: ast::Name) {
         if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
-            self.live_symbols.insert(def.struct_variant().field_named(name).did.node);
+            self.insert_def_id(def.struct_variant().field_named(name).did);
         } else {
             self.tcx.sess.span_bug(lhs.span, "named field access on non-struct")
         }
@@ -121,7 +128,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
     fn handle_tup_field_access(&mut self, lhs: &hir::Expr, idx: usize) {
         if let ty::TyStruct(def, _) = self.tcx.expr_ty_adjusted(lhs).sty {
-            self.live_symbols.insert(def.struct_variant().fields[idx].did.node);
+            self.insert_def_id(def.struct_variant().fields[idx].did);
         }
     }
 
@@ -137,7 +144,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
             if let hir::PatWild(hir::PatWildSingle) = pat.node.pat.node {
                 continue;
             }
-            self.live_symbols.insert(variant.field_named(pat.node.name).did.node);
+            self.insert_def_id(variant.field_named(pat.node.name).did);
         }
     }
 
@@ -469,8 +476,10 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
     // `ctor_id`. On the other hand, in a statement like
     // `type <ident> <generics> = <ty>;` where <ty> refers to a struct_ctor,
     // DefMap maps <ty> to `id` instead.
-    fn symbol_is_live(&mut self, id: ast::NodeId,
-                      ctor_id: Option<ast::NodeId>) -> bool {
+    fn symbol_is_live(&mut self,
+                      id: ast::NodeId,
+                      ctor_id: Option<ast::NodeId>)
+                      -> bool {
         if self.live_symbols.contains(&id)
            || ctor_id.map_or(false,
                              |ctor| self.live_symbols.contains(&ctor)) {
@@ -486,9 +495,11 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
             Some(impl_list) => {
                 for impl_did in impl_list.iter() {
                     for item_did in impl_items.get(impl_did).unwrap().iter() {
-                        if self.live_symbols.contains(&item_did.def_id()
-                                                               .node) {
-                            return true;
+                        if let Some(item_node_id) =
+                                self.tcx.map.as_local_node_id(item_did.def_id()) {
+                            if self.live_symbols.contains(&item_node_id) {
+                                return true;
+                            }
                         }
                     }
                 }
diff --git a/src/librustc/middle/def_id.rs b/src/librustc/middle/def_id.rs
index bbfaffb1112..f8f3412c8bb 100644
--- a/src/librustc/middle/def_id.rs
+++ b/src/librustc/middle/def_id.rs
@@ -17,13 +17,13 @@ use std::fmt;
            RustcDecodable, Hash, Copy)]
 pub struct DefId {
     pub krate: CrateNum,
-    pub node: NodeId,
+    pub xxx_node: NodeId,
 }
 
 impl fmt::Debug for DefId {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "DefId {{ krate: {}, node: {}",
-                    self.krate, self.node));
+                    self.krate, self.xxx_node));
 
         // Unfortunately, there seems to be no way to attempt to print
         // a path for a def-id, so I'll just make a best effort for now
@@ -42,13 +42,7 @@ impl fmt::Debug for DefId {
 
 impl DefId {
     pub fn xxx_local(id: NodeId) -> DefId {
-        DefId { krate: LOCAL_CRATE, node: id }
-    }
-
-    /// Read the node id, asserting that this def-id is krate-local.
-    pub fn local_id(&self) -> NodeId {
-        assert_eq!(self.krate, LOCAL_CRATE);
-        self.node
+        DefId { krate: LOCAL_CRATE, xxx_node: id }
     }
 
     pub fn is_local(&self) -> bool {
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 262c5c1422b..73313a5c257 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -209,7 +209,7 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
         let crate_store = &self.session.cstore;
         crate_store.iter_crate_data(|crate_number, _crate_metadata| {
             each_lang_item(crate_store, crate_number, |node_id, item_index| {
-                let def_id = DefId { krate: crate_number, node: node_id };
+                let def_id = DefId { krate: crate_number, xxx_node: node_id };
                 self.collect_item(item_index, def_id, DUMMY_SP);
                 true
             });
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index ec7274a9b6d..48550c3d8b2 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -219,7 +219,7 @@ pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> hir::Path {
 }
 
 /// Return variants that are necessary to exist for the pattern to match.
-pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<ast::NodeId> {
+pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
     let mut variants = vec![];
     walk_pat(pat, |p| {
         match p.node {
@@ -228,7 +228,7 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<ast::NodeId> {
             hir::PatStruct(..) => {
                 match dm.borrow().get(&p.id) {
                     Some(&PathResolution { base_def: DefVariant(_, id, _), .. }) => {
-                        variants.push(id.node); // XXX
+                        variants.push(id);
                     }
                     _ => ()
                 }
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index bbf310b65c3..a89da9704d9 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -16,7 +16,6 @@
 // reachable as well.
 
 use front::map as ast_map;
-use metadata::cstore::LOCAL_CRATE;
 use middle::def;
 use middle::def_id::DefId;
 use middle::ty;
@@ -62,20 +61,15 @@ fn method_might_be_inlined(tcx: &ty::ctxt, sig: &hir::MethodSig,
         generics_require_inlining(&sig.generics) {
         return true
     }
-    if impl_src.is_local() {
-        {
-            match tcx.map.find(impl_src.node) {
-                Some(ast_map::NodeItem(item)) => {
-                    item_might_be_inlined(&*item)
-                }
-                Some(..) | None => {
-                    tcx.sess.span_bug(impl_item.span, "impl did is not an item")
-                }
-            }
+    if let Some(impl_node_id) = tcx.map.as_local_node_id(impl_src) {
+        match tcx.map.find(impl_node_id) {
+            Some(ast_map::NodeItem(item)) =>
+                item_might_be_inlined(&*item),
+            Some(..) | None =>
+                tcx.sess.span_bug(impl_item.span, "impl did is not an item")
         }
     } else {
-        tcx.sess.span_bug(impl_item.span, "found a foreign impl as a parent \
-                                           of a local method")
+        tcx.sess.span_bug(impl_item.span, "found a foreign impl as a parent of a local method")
     }
 }
 
@@ -107,22 +101,22 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
                 };
 
                 let def_id = def.def_id();
-                if def_id.is_local() {
+                if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
                     if self.def_id_represents_local_inlined_item(def_id) {
-                        self.worklist.push(def_id.node)
+                        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::DefConst(..) | def::DefAssociatedConst(..) => {
-                                self.worklist.push(def_id.node);
+                                self.worklist.push(node_id);
                             }
 
                             // If this wasn't a static, then the destination is
                             // surely reachable.
                             _ => {
-                                self.reachable_symbols.insert(def_id.node);
+                                self.reachable_symbols.insert(node_id);
                             }
                         }
                     }
@@ -133,11 +127,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
                 let def_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
                 match self.tcx.impl_or_trait_item(def_id).container() {
                     ty::ImplContainer(_) => {
-                        if def_id.is_local() {
+                        if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
                             if self.def_id_represents_local_inlined_item(def_id) {
-                                self.worklist.push(def_id.node)
+                                self.worklist.push(node_id)
                             }
-                            self.reachable_symbols.insert(def_id.node);
+                            self.reachable_symbols.insert(node_id);
                         }
                     }
                     ty::TraitContainer(_) => {}
@@ -172,11 +166,11 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
     // Returns true if the given def ID represents a local item that is
     // eligible for inlining and false otherwise.
     fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
-        if def_id.krate != LOCAL_CRATE {
-            return false
-        }
+        let node_id = match self.tcx.map.as_local_node_id(def_id) {
+            Some(node_id) => node_id,
+            None => { return false; }
+        };
 
-        let node_id = def_id.node;
         match self.tcx.map.find(node_id) {
             Some(ast_map::NodeItem(item)) => {
                 match item.node {
@@ -205,11 +199,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                             // Check the impl. If the generics on the self
                             // type of the impl require inlining, this method
                             // does too.
-                            assert!(impl_did.is_local());
-                            match self.tcx
-                                      .map
-                                      .expect_item(impl_did.node)
-                                      .node {
+                            let impl_node_id = self.tcx.map.as_local_node_id(impl_did).unwrap();
+                            match self.tcx.map.expect_item(impl_node_id).node {
                                 hir::ItemImpl(_, _, ref generics, _, _, _) => {
                                     generics_require_inlining(generics)
                                 }
@@ -355,8 +346,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
         drop_trait.for_each_impl(self.tcx, |drop_impl| {
             for destructor in &self.tcx.impl_items.borrow()[&drop_impl] {
                 let destructor_did = destructor.def_id();
-                if destructor_did.is_local() {
-                    self.reachable_symbols.insert(destructor_did.node);
+                if let Some(destructor_node_id) = self.tcx.map.as_local_node_id(destructor_did) {
+                    self.reachable_symbols.insert(destructor_node_id);
                 }
             }
         })
@@ -378,8 +369,10 @@ pub fn find_reachable(tcx: &ty::ctxt,
     }
     for (_, item) in tcx.lang_items.items() {
         match *item {
-            Some(did) if did.is_local() => {
-                reachable_context.worklist.push(did.node);
+            Some(did) => {
+                if let Some(node_id) = tcx.map.as_local_node_id(did) {
+                    reachable_context.worklist.push(node_id);
+                }
             }
             _ => {}
         }
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index b6a4c97b180..15a7dd426fb 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -383,7 +383,7 @@ pub fn check_item(tcx: &ty::ctxt, item: &hir::Item, warn_about_defns: bool,
                 Some(cnum) => cnum,
                 None => return,
             };
-            let id = DefId { krate: cnum, node: ast::CRATE_NODE_ID };
+            let id = DefId { krate: cnum, xxx_node: ast::CRATE_NODE_ID };
             maybe_do_stability_check(tcx, id, item.span, cb);
         }
 
diff --git a/src/librustc/middle/ty/error.rs b/src/librustc/middle/ty/error.rs
index ba7be3e2c99..61536934aae 100644
--- a/src/librustc/middle/ty/error.rs
+++ b/src/librustc/middle/ty/error.rs
@@ -302,13 +302,15 @@ impl<'tcx> ty::ctxt<'tcx> {
                                              expected.ty,
                                              found.ty));
 
-                match (expected.def_id.is_local(),
-                       self.map.opt_span(expected.def_id.node)) {
-                    (true, Some(span)) => {
+                match
+                    self.map.as_local_node_id(expected.def_id)
+                            .and_then(|node_id| self.map.opt_span(node_id))
+                {
+                    Some(span) => {
                         self.sess.span_note(span,
                                             &format!("a default was defined here..."));
                     }
-                    (_, _) => {
+                    None => {
                         self.sess.note(
                             &format!("a default is defined on `{}`",
                                      self.item_path_str(expected.def_id)));
@@ -319,13 +321,15 @@ impl<'tcx> ty::ctxt<'tcx> {
                     expected.origin_span,
                     &format!("...that was applied to an unconstrained type variable here"));
 
-                match (found.def_id.is_local(),
-                       self.map.opt_span(found.def_id.node)) {
-                    (true, Some(span)) => {
+                match
+                    self.map.as_local_node_id(found.def_id)
+                            .and_then(|node_id| self.map.opt_span(node_id))
+                {
+                    Some(span) => {
                         self.sess.span_note(span,
                                             &format!("a second default was defined here..."));
                     }
-                    (_, _) => {
+                    None => {
                         self.sess.note(
                             &format!("a second default is defined on `{}`",
                                      self.item_path_str(found.def_id)));
diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs
index a48d34281bb..1b334e37722 100644
--- a/src/librustc/middle/ty/mod.rs
+++ b/src/librustc/middle/ty/mod.rs
@@ -618,7 +618,7 @@ pub struct RegionParameterDef {
 impl RegionParameterDef {
     pub fn to_early_bound_region(&self) -> ty::Region {
         ty::ReEarlyBound(ty::EarlyBoundRegion {
-            param_id: self.def_id,
+            def_id: self.def_id,
             space: self.space,
             index: self.index,
             name: self.name,
@@ -2101,8 +2101,8 @@ impl<'tcx> ctxt<'tcx> {
     }
 
     pub fn provided_trait_methods(&self, id: DefId) -> Vec<Rc<Method<'tcx>>> {
-        if id.is_local() {
-            if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node {
+        if let Some(id) = self.map.as_local_node_id(id) {
+            if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id).node {
                 ms.iter().filter_map(|ti| {
                     if let hir::MethodTraitItem(_, Some(_)) = ti.node {
                         match self.impl_or_trait_item(self.map.local_def_id(ti.id)) {
@@ -2126,8 +2126,8 @@ impl<'tcx> ctxt<'tcx> {
     }
 
     pub fn associated_consts(&self, id: DefId) -> Vec<Rc<AssociatedConst<'tcx>>> {
-        if id.is_local() {
-            match self.map.expect_item(id.node).node {
+        if let Some(id) = self.map.as_local_node_id(id) {
+            match self.map.expect_item(id).node {
                 ItemTrait(_, _, _, ref tis) => {
                     tis.iter().filter_map(|ti| {
                         if let hir::ConstTraitItem(_, _) = ti.node {
@@ -2187,8 +2187,8 @@ impl<'tcx> ctxt<'tcx> {
     }
 
     pub fn trait_impl_polarity(&self, id: DefId) -> Option<hir::ImplPolarity> {
-        if id.is_local() {
-            match self.map.find(id.node) {
+        if let Some(id) = self.map.as_local_node_id(id) {
+            match self.map.find(id) {
                 Some(ast_map::NodeItem(item)) => {
                     match item.node {
                         hir::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
@@ -2243,9 +2243,9 @@ impl<'tcx> ctxt<'tcx> {
 
     /// Returns whether this DefId refers to an impl
     pub fn is_impl(&self, id: DefId) -> bool {
-        if id.is_local() {
+        if let Some(id) = self.map.as_local_node_id(id) {
             if let Some(ast_map::NodeItem(
-                &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id.node) {
+                &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id) {
                 true
             } else {
                 false
@@ -2266,16 +2266,16 @@ impl<'tcx> ctxt<'tcx> {
     pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
         F: FnOnce(ast_map::PathElems) -> T,
     {
-        if id.is_local() {
-            self.map.with_path(id.node, f)
+        if let Some(id) = self.map.as_local_node_id(id) {
+            self.map.with_path(id, f)
         } else {
             f(csearch::get_item_path(self, id).iter().cloned().chain(LinkedPath::empty()))
         }
     }
 
     pub fn item_name(&self, id: DefId) -> ast::Name {
-        if id.is_local() {
-            self.map.get_path_elem(id.node).name()
+        if let Some(id) = self.map.as_local_node_id(id) {
+            self.map.get_path_elem(id).name()
         } else {
             csearch::get_item_name(self, id)
         }
@@ -2335,8 +2335,8 @@ impl<'tcx> ctxt<'tcx> {
 
     /// Get the attributes of a definition.
     pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [ast::Attribute]> {
-        if did.is_local() {
-            Cow::Borrowed(self.map.attrs(did.node))
+        if let Some(id) = self.map.as_local_node_id(did) {
+            Cow::Borrowed(self.map.attrs(id))
         } else {
             Cow::Owned(csearch::get_item_attrs(&self.sess.cstore, did))
         }
diff --git a/src/librustc/middle/ty/sty.rs b/src/librustc/middle/ty/sty.rs
index c553e3ca5b3..c6debc38227 100644
--- a/src/librustc/middle/ty/sty.rs
+++ b/src/librustc/middle/ty/sty.rs
@@ -675,7 +675,7 @@ pub enum Region {
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
 pub struct EarlyBoundRegion {
-    pub param_id: DefId,
+    pub def_id: DefId,
     pub space: subst::ParamSpace,
     pub index: u32,
     pub name: Name,
diff --git a/src/librustc/middle/ty/util.rs b/src/librustc/middle/ty/util.rs
index a431bbaeeb8..2e6cc4faff8 100644
--- a/src/librustc/middle/ty/util.rs
+++ b/src/librustc/middle/ty/util.rs
@@ -461,7 +461,7 @@ impl<'tcx> ty::ctxt<'tcx> {
                     tcx.sess.cstore.get_crate_hash(did.krate)
                 };
                 h.as_str().hash(state);
-                did.node.hash(state);
+                did.xxx_node.hash(state);
             };
             let mt = |state: &mut SipHasher, mt: TypeAndMut| {
                 mt.mutbl.hash(state);
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 8daaf1325ea..75099ca24bc 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -309,18 +309,18 @@ impl<'tcx> fmt::Display for ty::TraitTy<'tcx> {
 
 impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "TypeParameterDef({}, {}:{}, {:?}/{})",
+        write!(f, "TypeParameterDef({}, {:?}, {:?}/{})",
                self.name,
-               self.def_id.krate, self.def_id.node,
+               self.def_id,
                self.space, self.index)
     }
 }
 
 impl fmt::Debug for ty::RegionParameterDef {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "RegionParameterDef({}, {}:{}, {:?}/{}, {:?})",
+        write!(f, "RegionParameterDef({}, {:?}, {:?}/{}, {:?})",
                self.name,
-               self.def_id.krate, self.def_id.node,
+               self.def_id,
                self.space, self.index,
                self.bounds)
     }
@@ -455,7 +455,7 @@ impl fmt::Debug for ty::BoundRegion {
             BrAnon(n) => write!(f, "BrAnon({:?})", n),
             BrFresh(n) => write!(f, "BrFresh({:?})", n),
             BrNamed(did, name) => {
-                write!(f, "BrNamed({}:{}, {:?})", did.krate, did.node, name)
+                write!(f, "BrNamed({:?}, {:?})", did, name)
             }
             BrEnv => "BrEnv".fmt(f),
         }
@@ -467,7 +467,7 @@ impl fmt::Debug for ty::Region {
         match *self {
             ty::ReEarlyBound(ref data) => {
                 write!(f, "ReEarlyBound({:?}, {:?}, {}, {})",
-                       data.param_id,
+                       data.def_id,
                        data.space,
                        data.index,
                        data.name)
@@ -888,13 +888,13 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
             TyTrait(ref data) => write!(f, "{}", data),
             ty::TyProjection(ref data) => write!(f, "{}", data),
             TyStr => write!(f, "str"),
-            TyClosure(ref did, ref substs) => ty::tls::with(|tcx| {
+            TyClosure(did, ref substs) => ty::tls::with(|tcx| {
                 try!(write!(f, "[closure"));
 
-                if did.is_local() {
-                    try!(write!(f, "@{:?}", tcx.map.span(did.node)));
+                if let Some(node_id) = tcx.map.as_local_node_id(did) {
+                    try!(write!(f, "@{:?}", tcx.map.span(node_id)));
                     let mut sep = " ";
-                    try!(tcx.with_freevars(did.node, |freevars| {
+                    try!(tcx.with_freevars(node_id, |freevars| {
                         for (freevar, upvar_ty) in freevars.iter().zip(&substs.upvar_tys) {
                             let node_id = freevar.def.node_id();
                             try!(write!(f,
diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs
index 4766fd0cfb7..175bac01daa 100644
--- a/src/librustc_borrowck/borrowck/fragments.rs
+++ b/src/librustc_borrowck/borrowck/fragments.rs
@@ -20,7 +20,6 @@ use borrowck::LoanPathKind::{LpVar, LpUpvar, LpDowncast, LpExtend};
 use borrowck::LoanPathElem::{LpDeref, LpInterior};
 use borrowck::move_data::InvalidMovePathIndex;
 use borrowck::move_data::{MoveData, MovePathIndex};
-use rustc::metadata::cstore::LOCAL_CRATE;
 use rustc::middle::def_id::{DefId};
 use rustc::middle::ty;
 use rustc::middle::mem_categorization as mc;
@@ -134,7 +133,7 @@ pub fn build_unfragmented_map(this: &mut borrowck::BorrowckCtxt,
     }
 
     let mut fraginfo_map = this.tcx.fragment_infos.borrow_mut();
-    let fn_did = DefId { krate: LOCAL_CRATE, node: id };
+    let fn_did = this.tcx.map.local_def_id(id);
     let prev = fraginfo_map.insert(fn_did, fragment_infos);
     assert!(prev.is_none());
 }
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 4b3b3a5e848..dc550bb698f 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -295,7 +295,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
     {
         let name = token::intern(name);
         ty::ReEarlyBound(ty::EarlyBoundRegion {
-            param_id: ast::DUMMY_NODE_ID,
+            def_id: self.infcx.tcx.map.local_def_id(ast::DUMMY_NODE_ID),
             space: space,
             index: index,
             name: name
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 9d502a31261..d4cf85d236f 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -202,10 +202,12 @@ impl LateLintPass for RawPointerDerive {
             }
             _ => return,
         };
-        if !did.is_local() {
+        let node_id = if let Some(node_id) = cx.tcx.map.as_local_node_id(did) {
+            node_id
+        } else {
             return;
-        }
-        let item = match cx.tcx.map.find(did.node) {
+        };
+        let item = match cx.tcx.map.find(node_id) {
             Some(hir_map::NodeItem(item)) => item,
             _ => return,
         };
@@ -458,13 +460,15 @@ impl LateLintPass for MissingDoc {
                 // If the trait is private, add the impl items to private_traits so they don't get
                 // reported for missing docs.
                 let real_trait = cx.tcx.trait_ref_to_def_id(trait_ref);
-                match cx.tcx.map.find(real_trait.node) {
-                    Some(hir_map::NodeItem(item)) => if item.vis == hir::Visibility::Inherited {
-                        for itm in impl_items {
-                            self.private_traits.insert(itm.id);
-                        }
-                    },
-                    _ => { }
+                if let Some(node_id) = cx.tcx.map.as_local_node_id(real_trait) {
+                    match cx.tcx.map.find(node_id) {
+                        Some(hir_map::NodeItem(item)) => if item.vis == hir::Visibility::Inherited {
+                            for itm in impl_items {
+                                self.private_traits.insert(itm.id);
+                            }
+                        },
+                        _ => { }
+                    }
                 }
                 return
             },
@@ -629,9 +633,11 @@ impl LateLintPass for MissingDebugImplementations {
             let debug_def = cx.tcx.lookup_trait_def(debug);
             let mut impls = NodeSet();
             debug_def.for_each_impl(cx.tcx, |d| {
-                if d.is_local() {
-                    if let Some(ty_def) = cx.tcx.node_id_to_type(d.node).ty_to_def_id() {
-                        impls.insert(ty_def.node);
+                if let Some(n) = cx.tcx.map.as_local_node_id(d) {
+                    if let Some(ty_def) = cx.tcx.node_id_to_type(n).ty_to_def_id() {
+                        if let Some(node_id) = cx.tcx.map.as_local_node_id(ty_def) {
+                            impls.insert(node_id);
+                        }
                     }
                 }
             });
@@ -956,7 +962,12 @@ impl LateLintPass for UnconditionalRecursion {
                         traits::Obligation::new(traits::ObligationCause::misc(span, expr_id),
                                                 trait_ref.to_poly_trait_predicate());
 
-                    let param_env = ty::ParameterEnvironment::for_item(tcx, method.def_id.node);
+                    // unwrap() is ok here b/c `method` is the method
+                    // defined in this crate whose body we are
+                    // checking, so it's always local
+                    let node_id = tcx.map.as_local_node_id(method.def_id).unwrap();
+
+                    let param_env = ty::ParameterEnvironment::for_item(tcx, node_id);
                     let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env), false);
                     let mut selcx = traits::SelectionContext::new(&infcx);
                     match selcx.select(&obligation) {
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 920ecab7527..f3549e6dda7 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -139,8 +139,8 @@ impl LateLintPass for UnusedResults {
             ty::TyBool => return,
             ty::TyStruct(def, _) |
             ty::TyEnum(def, _) => {
-                if def.did.is_local() {
-                    if let hir_map::NodeItem(it) = cx.tcx.map.get(def.did.node) {
+                if let Some(def_node_id) = cx.tcx.map.as_local_node_id(def.did) {
+                    if let hir_map::NodeItem(it) = cx.tcx.map.get(def_node_id) {
                         check_must_use(cx, &it.attrs, s.span)
                     } else {
                         false
diff --git a/src/librustc_mir/tcx/expr.rs b/src/librustc_mir/tcx/expr.rs
index 6560f8449c4..baa3346f831 100644
--- a/src/librustc_mir/tcx/expr.rs
+++ b/src/librustc_mir/tcx/expr.rs
@@ -817,7 +817,7 @@ fn capture_freevar<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
                                freevar: &ty::Freevar,
                                freevar_ty: Ty<'tcx>)
                                -> ExprRef<Cx<'a,'tcx>> {
-    let id_var = freevar.def.def_id().node;
+    let id_var = freevar.def.node_id();
     let upvar_id = ty::UpvarId { var_id: id_var, closure_expr_id: closure_expr.id };
     let upvar_capture = cx.tcx.upvar_capture(upvar_id).unwrap();
     let temp_lifetime = cx.tcx.region_maps.temporary_scope(closure_expr.id);
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index aa41dccc6dc..13b9b16e6ca 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -265,8 +265,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
                             def::DefPrimTy(..) => true,
                             def => {
                                 let did = def.def_id();
-                                !did.is_local() ||
-                                 self.exported_items.contains(&did.node)
+                                if let Some(node_id) = self.tcx.map.as_local_node_id(did) {
+                                    self.exported_items.contains(&node_id)
+                                } else {
+                                    true
+                                }
                             }
                         }
                     }
@@ -274,8 +277,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
                 };
                 let tr = self.tcx.impl_trait_ref(self.tcx.map.local_def_id(item.id));
                 let public_trait = tr.clone().map_or(false, |tr| {
-                    !tr.def_id.is_local() ||
-                     self.exported_items.contains(&tr.def_id.node)
+                    if let Some(node_id) = self.tcx.map.as_local_node_id(tr.def_id) {
+                        self.exported_items.contains(&node_id)
+                    } else {
+                        true
+                    }
                 });
 
                 if public_ty || public_trait {
@@ -334,8 +340,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
                         def::DefPrimTy(..) | def::DefTyParam(..) => {},
                         def => {
                             let did = def.def_id();
-                            if did.is_local() {
-                                self.exported_items.insert(did.node);
+                            if let Some(node_id) = self.tcx.map.as_local_node_id(did) {
+                                self.exported_items.insert(node_id);
                             }
                         }
                     }
@@ -363,8 +369,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
         if self.prev_exported {
             assert!(self.export_map.contains_key(&id), "wut {}", id);
             for export in self.export_map.get(&id).unwrap() {
-                if export.def_id.is_local() {
-                    self.reexports.insert(export.def_id.node);
+                if let Some(node_id) = self.tcx.map.as_local_node_id(export.def_id) {
+                    self.reexports.insert(node_id);
                 }
             }
         }
@@ -404,7 +410,9 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
     // Determines whether the given definition is public from the point of view
     // of the current item.
     fn def_privacy(&self, did: DefId) -> PrivacyResult {
-        if !did.is_local() {
+        let node_id = if let Some(node_id) = self.tcx.map.as_local_node_id(did) {
+            node_id
+        } else {
             if self.external_exports.contains(&did) {
                 debug!("privacy - {:?} was externally exported", did);
                 return Allowable;
@@ -496,19 +504,19 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                     ExternallyDenied
                 }
             };
-        }
+        };
 
         debug!("privacy - local {} not public all the way down",
-               self.tcx.map.node_to_string(did.node));
+               self.tcx.map.node_to_string(node_id));
         // return quickly for things in the same module
-        if self.parents.get(&did.node) == self.parents.get(&self.curitem) {
+        if self.parents.get(&node_id) == self.parents.get(&self.curitem) {
             debug!("privacy - same parent, we're done here");
             return Allowable;
         }
 
         // We now know that there is at least one private member between the
         // destination and the root.
-        let mut closest_private_id = did.node;
+        let mut closest_private_id = node_id;
         loop {
             debug!("privacy - examining {}", self.nodestr(closest_private_id));
             let vis = match self.tcx.map.find(closest_private_id) {
@@ -578,6 +586,15 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
         }
     }
 
+    /// True if `id` is both local and private-accessible
+    fn local_private_accessible(&self, did: DefId) -> bool {
+        if let Some(node_id) = self.tcx.map.as_local_node_id(did) {
+            self.private_accessible(node_id)
+        } else {
+            false
+        }
+    }
+
     /// For a local private node in the AST, this function will determine
     /// whether the node is accessible by the current module that iteration is
     /// inside.
@@ -639,11 +656,15 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             DisallowedBy(id) => id,
         };
 
-        // If we're disallowed by a particular id, then we attempt to give a
-        // nice error message to say why it was disallowed. It was either
-        // because the item itself is private or because its parent is private
-        // and its parent isn't in our ancestry.
-        let (err_span, err_msg) = if id == source_did.unwrap_or(to_check).node {
+        // If we're disallowed by a particular id, then we attempt to
+        // give a nice error message to say why it was disallowed. It
+        // was either because the item itself is private or because
+        // its parent is private and its parent isn't in our
+        // ancestry. (Both the item being checked and its parent must
+        // be local.)
+        let def_id = source_did.unwrap_or(to_check);
+        let node_id = self.tcx.map.as_local_node_id(def_id).unwrap();
+        let (err_span, err_msg) = if id == node_id {
             return Some((span, format!("{} is private", msg), None));
         } else {
             (span, format!("{} is inaccessible", msg))
@@ -663,8 +684,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
                         };
                         let def = self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def();
                         let did = def.def_id();
-                        assert!(did.is_local());
-                        match self.tcx.map.get(did.node) {
+                        let node_id = self.tcx.map.as_local_node_id(did).unwrap();
+                        match self.tcx.map.get(node_id) {
                             ast_map::NodeItem(item) => item,
                             _ => self.tcx.sess.span_bug(item.span,
                                                         "path is not an item")
@@ -699,9 +720,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
             }
             UnnamedField(idx) => &v.fields[idx]
         };
-        if field.vis == hir::Public ||
-            (field.did.is_local() && self.private_accessible(field.did.node)) {
-            return
+        if field.vis == hir::Public || self.local_private_accessible(field.did) {
+            return;
         }
 
         let struct_desc = match def.adt_kind() {
@@ -891,11 +911,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
                         _ => expr_ty
                     }.ty_adt_def().unwrap();
                     let any_priv = def.struct_variant().fields.iter().any(|f| {
-                        f.vis != hir::Public && (
-                            !f.did.is_local() ||
-                                    !self.private_accessible(f.did.node))
-                        });
-
+                        f.vis != hir::Public && !self.local_private_accessible(f.did)
+                    });
                     if any_priv {
                         span_err!(self.tcx.sess, expr.span, E0450,
                                   "cannot invoke tuple struct constructor with private \
@@ -1134,18 +1151,19 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
             None | Some(def::DefPrimTy(..)) => return false,
             Some(def) => def.def_id(),
         };
+
         // A path can only be private if:
         // it's in this crate...
-        if !did.is_local() {
+        if let Some(node_id) = self.tcx.map.as_local_node_id(did) {
+            // .. and it corresponds to a private type in the AST (this returns
+            // None for type parameters)
+            match self.tcx.map.find(node_id) {
+                Some(ast_map::NodeItem(ref item)) => item.vis != hir::Public,
+                Some(_) | None => false,
+            }
+        } else {
             return false
         }
-
-        // .. and it corresponds to a private type in the AST (this returns
-        // None for type parameters)
-        match self.tcx.map.find(did.node) {
-            Some(ast_map::NodeItem(ref item)) => item.vis != hir::Public,
-            Some(_) | None => false,
-        }
     }
 
     fn trait_is_public(&self, trait_id: ast::NodeId) -> bool {
@@ -1245,7 +1263,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
                                               |tr| {
                         let did = self.tcx.trait_ref_to_def_id(tr);
 
-                        !did.is_local() || self.trait_is_public(did.node)
+                        if let Some(node_id) = self.tcx.map.as_local_node_id(did) {
+                            self.trait_is_public(node_id)
+                        } else {
+                            true // external traits must be public
+                        }
                     });
 
                 // `true` iff this is a trait impl or at least one method is public.
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 1f850fc9687..3a53c8b4d8c 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -387,7 +387,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             ItemExternCrate(_) => {
                 // n.b. we don't need to look at the path option here, because cstore already did
                 if let Some(crate_id) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
-                    let def_id = DefId { krate: crate_id, node: 0 };
+                    let def_id = DefId { krate: crate_id, xxx_node: 0 };
                     self.external_exports.insert(def_id);
                     let parent_link = ModuleParentLink(Rc::downgrade(parent), name);
                     let external_module = Rc::new(Module::new(parent_link,
@@ -409,7 +409,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp);
 
                 let parent_link = self.get_parent_link(parent, name);
-                let def_id = DefId { krate: 0, node: item.id };
+                let def_id = self.ast_map.local_def_id(item.id);
                 name_bindings.define_module(parent_link,
                                             Some(def_id),
                                             NormalModuleKind,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 4497bfb3898..e828c319a2b 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -65,7 +65,7 @@ use rustc::util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
 use rustc::util::lev_distance::lev_distance;
 
 use syntax::ast;
-use syntax::ast::{Ident, Name, NodeId, CrateNum, TyIs, TyI8, TyI16, TyI32, TyI64};
+use syntax::ast::{CRATE_NODE_ID, Ident, Name, NodeId, CrateNum, TyIs, TyI8, TyI16, TyI32, TyI64};
 use syntax::ast::{TyUs, TyU8, TyU16, TyU32, TyU64, TyF64, TyF32};
 use syntax::attr::AttrMetaMethods;
 use syntax::ext::mtwt;
@@ -1188,8 +1188,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
            make_glob_map: MakeGlobMap) -> Resolver<'a, 'tcx> {
         let graph_root = NameBindings::new();
 
+        let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
         graph_root.define_module(NoParentLink,
-                                 Some(DefId { krate: 0, node: 0 }),
+                                 Some(root_def_id),
                                  NormalModuleKind,
                                  false,
                                  true,
@@ -1257,8 +1258,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     }
 
     fn get_trait_name(&self, did: DefId) -> Name {
-        if did.is_local() {
-            self.ast_map.expect_item(did.node).name
+        if let Some(node_id) = self.ast_map.as_local_node_id(did) {
+            self.ast_map.expect_item(node_id).name
         } else {
             csearch::get_trait_name(&self.session.cstore, did)
         }
@@ -3498,8 +3499,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         fn is_static_method(this: &Resolver, did: DefId) -> bool {
-            if did.is_local() {
-                let sig = match this.ast_map.get(did.node) {
+            if let Some(node_id) = this.ast_map.as_local_node_id(did) {
+                let sig = match this.ast_map.get(node_id) {
                     hir_map::NodeTraitItem(trait_item) => match trait_item.node {
                         hir::MethodTraitItem(ref sig, _) => sig,
                         _ => return false
@@ -3846,9 +3847,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         fn add_trait_info(found_traits: &mut Vec<DefId>,
                           trait_def_id: DefId,
                           name: Name) {
-            debug!("(adding trait info) found trait {}:{} for method '{}'",
-                trait_def_id.krate,
-                trait_def_id.node,
+            debug!("(adding trait info) found trait {:?} for method '{}'",
+                trait_def_id,
                 name);
             found_traits.push(trait_def_id);
         }
diff --git a/src/librustc_resolve/record_exports.rs b/src/librustc_resolve/record_exports.rs
index 076b2fcc004..0eb1e2cc06f 100644
--- a/src/librustc_resolve/record_exports.rs
+++ b/src/librustc_resolve/record_exports.rs
@@ -102,9 +102,9 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
         self.add_exports_for_module(&mut exports, module_);
         match module_.def_id.get() {
             Some(def_id) => {
-                self.export_map.insert(def_id.node, exports); // XXX
-                debug!("(computing exports) writing exports for {} (some)",
-                       def_id.node);
+                let node_id = self.ast_map.as_local_node_id(def_id).unwrap();
+                self.export_map.insert(node_id, exports);
+                debug!("(computing exports) writing exports for {} (some)", node_id);
             }
             None => {}
         }
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index c2ec4456e11..9f963d54dc5 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use metadata::cstore::LOCAL_CRATE;
 use middle::ty;
 use middle::def;
 use middle::def_id::DefId;
@@ -350,8 +349,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         // The qualname for a method is the trait name or name of the struct in an impl in
         // which the method is declared in, followed by the method's name.
         let qualname = match self.tcx.impl_of_method(self.tcx.map.local_def_id(id)) {
-            Some(impl_id) => match self.tcx.map.get(impl_id.node) {
-                NodeItem(item) => {
+            Some(impl_id) => match self.tcx.map.get_if_local(impl_id) {
+                Some(NodeItem(item)) => {
                     match item.node {
                         hir::ItemImpl(_, _, _, _, ref ty, _) => {
                             let mut result = String::from("<");
@@ -370,27 +369,27 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                         }
                         _ => {
                             self.tcx.sess.span_bug(span,
-                                &format!("Container {} for method {} not an impl?",
-                                         impl_id.node, id));
+                                &format!("Container {:?} for method {} not an impl?",
+                                         impl_id, id));
                         }
                     }
                 }
-                _ => {
+                r => {
                     self.tcx.sess.span_bug(span,
-                        &format!("Container {} for method {} is not a node item {:?}",
-                                 impl_id.node, id, self.tcx.map.get(impl_id.node)));
-                }
+                        &format!("Container {:?} for method {} is not a node item {:?}",
+                                 impl_id, id, r));
+                },
             },
             None => match self.tcx.trait_of_item(self.tcx.map.local_def_id(id)) {
                 Some(def_id) => {
-                    match self.tcx.map.get(def_id.node) {
-                        NodeItem(_) => {
+                    match self.tcx.map.get_if_local(def_id) {
+                        Some(NodeItem(_)) => {
                             format!("::{}", self.tcx.item_path_str(def_id))
                         }
-                        _ => {
+                        r => {
                             self.tcx.sess.span_bug(span,
-                                &format!("Could not find container {} for method {}",
-                                         def_id.node, id));
+                                &format!("Could not find container {:?} for method {}, got {:?}",
+                                         def_id, id, r));
                         }
                     }
                 }
@@ -408,7 +407,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             self.tcx.trait_item_of_item(def_id)
             .and_then(|new_id| {
                 let new_def_id = new_id.def_id();
-                if new_def_id.node != 0 && new_def_id != def_id {
+                if new_def_id != def_id {
                     Some(new_def_id)
                 } else {
                     None
@@ -598,13 +597,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
 
     fn trait_method_has_body(&self, mr: &ty::ImplOrTraitItem) -> bool {
         let def_id = mr.def_id();
-        if def_id.krate != LOCAL_CRATE {
-            return false;
-        }
-
-        let trait_item = self.tcx.map.expect_trait_item(def_id.node);
-        if let hir::TraitItem_::MethodTraitItem(_, Some(_)) = trait_item.node {
-            true
+        if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
+            let trait_item = self.tcx.map.expect_trait_item(node_id);
+            if let hir::TraitItem_::MethodTraitItem(_, Some(_)) = trait_item.node {
+                true
+            } else {
+                false
+            }
         } else {
             false
         }
diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs
index f8e68649853..769c1242998 100644
--- a/src/librustc_trans/save/recorder.rs
+++ b/src/librustc_trans/save/recorder.rs
@@ -21,7 +21,7 @@ use syntax::ast;
 use syntax::ast::NodeId;
 use syntax::codemap::*;
 
-const ZERO_DEF_ID: DefId = DefId { node: 0, krate: 0 };
+const ZERO_DEF_ID: DefId = DefId { xxx_node: 0, krate: 0 };
 
 pub struct Recorder {
     // output file
@@ -381,7 +381,7 @@ impl<'a> FmtStrs<'a> {
                       decl_id: Option<DefId>,
                       scope_id: NodeId) {
         let values = match decl_id {
-            Some(decl_id) => svec!(id, name, decl_id.node, decl_id.krate, scope_id),
+            Some(decl_id) => svec!(id, name, decl_id.xxx_node, decl_id.krate, scope_id),
             None => svec!(id, name, "", "", scope_id),
         };
         self.check_and_record(Function,
@@ -442,9 +442,9 @@ impl<'a> FmtStrs<'a> {
                               span,
                               sub_span,
                               svec!(id,
-                                    ref_id.node,
+                                    ref_id.xxx_node,
                                     ref_id.krate,
-                                    trait_id.node,
+                                    trait_id.xxx_node,
                                     trait_id.krate,
                                     scope_id));
     }
@@ -470,7 +470,7 @@ impl<'a> FmtStrs<'a> {
                          name: &str,
                          parent: NodeId) {
         let (mod_node, mod_crate) = match mod_id {
-            Some(mod_id) => (mod_id.node, mod_id.krate),
+            Some(mod_id) => (mod_id.xxx_node, mod_id.krate),
             None => (0, 0),
         };
         self.check_and_record(UseAlias,
@@ -513,7 +513,7 @@ impl<'a> FmtStrs<'a> {
         self.check_and_record(Inheritance,
                               span,
                               sub_span,
-                              svec!(base_id.node,
+                              svec!(base_id.xxx_node,
                                     base_id.krate,
                                     deriv_id,
                                     0));
@@ -527,7 +527,7 @@ impl<'a> FmtStrs<'a> {
         self.check_and_record(FnCall,
                               span,
                               sub_span,
-                              svec!(id.node, id.krate, "", scope_id));
+                              svec!(id.xxx_node, id.krate, "", scope_id));
     }
 
     pub fn meth_call_str(&mut self,
@@ -537,11 +537,11 @@ impl<'a> FmtStrs<'a> {
                          declid: Option<DefId>,
                          scope_id: NodeId) {
         let (dfn, dfk) = match defid {
-            Some(defid) => (defid.node, defid.krate),
+            Some(defid) => (defid.xxx_node, defid.krate),
             None => (0, 0),
         };
         let (dcn, dck) = match declid {
-            Some(declid) => (s!(declid.node), s!(declid.krate)),
+            Some(declid) => (s!(declid.xxx_node), s!(declid.krate)),
             None => ("".to_string(), "".to_string()),
         };
         self.check_and_record(MethodCall,
@@ -600,6 +600,6 @@ impl<'a> FmtStrs<'a> {
         self.check_and_record(kind,
                               span,
                               sub_span,
-                              svec!(id.node, id.krate, "", scope_id));
+                              svec!(id.xxx_node, id.krate, "", scope_id));
     }
 }
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 8a0578332e6..61244e32c7d 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -35,7 +35,6 @@ use lint;
 use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
 use llvm;
 use metadata::{csearch, encoder, loader};
-use metadata::cstore::LOCAL_CRATE;
 use middle::astencode;
 use middle::cfg;
 use middle::def_id::DefId;
@@ -1287,7 +1286,7 @@ pub fn init_function<'a, 'tcx>(fcx: &'a FunctionContext<'a, 'tcx>,
 
     // Create the drop-flag hints for every unfragmented path in the function.
     let tcx = fcx.ccx.tcx();
-    let fn_did = DefId { krate: LOCAL_CRATE, node: fcx.id };
+    let fn_did = tcx.map.local_def_id(fcx.id);
     let mut hints = fcx.lldropflag_hints.borrow_mut();
     let fragment_infos = tcx.fragment_infos.borrow();
 
@@ -2254,13 +2253,14 @@ pub fn create_entry_wrapper(ccx: &CrateContext,
                     Ok(id) => id,
                     Err(s) => { ccx.sess().fatal(&s[..]); }
                 };
-                let start_fn = if start_def_id.is_local() {
-                    get_item_val(ccx, start_def_id.node)
-                } else {
-                    let start_fn_type = csearch::get_type(ccx.tcx(),
-                                                          start_def_id).ty;
-                    trans_external_path(ccx, start_def_id, start_fn_type)
-                };
+                let start_fn =
+                    if let Some(start_node_id) = ccx.tcx().map.as_local_node_id(start_def_id) {
+                        get_item_val(ccx, start_node_id)
+                    } else {
+                        let start_fn_type = csearch::get_type(ccx.tcx(),
+                                                              start_def_id).ty;
+                        trans_external_path(ccx, start_def_id, start_fn_type)
+                    };
 
                 let args = {
                     let opaque_rust_main = llvm::LLVMBuildPointerCast(bld,
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 1704a8010dd..df9dd8feafa 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -140,8 +140,10 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
         match def {
             def::DefFn(did, _) if {
                 let maybe_def_id = inline::get_local_instance(bcx.ccx(), did);
-                let maybe_ast_node = maybe_def_id.and_then(|def_id| bcx.tcx().map
-                                                                             .find(def_id.node));
+                let maybe_ast_node = maybe_def_id.and_then(|def_id| {
+                    let node_id = bcx.tcx().map.as_local_node_id(def_id).unwrap();
+                    bcx.tcx().map.find(node_id)
+                });
                 match maybe_ast_node {
                     Some(hir_map::NodeStructCtor(_)) => true,
                     _ => false
@@ -162,7 +164,8 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
                                                     ExprId(ref_expr.id),
                                                     bcx.fcx.param_substs);
                 let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
-                Callee { bcx: bcx, data: Intrinsic(def_id.node, substs), ty: expr_ty }
+                let node_id = bcx.tcx().map.as_local_node_id(def_id).unwrap();
+                Callee { bcx: bcx, data: Intrinsic(node_id, substs), ty: expr_ty }
             }
             def::DefFn(did, _) => {
                 fn_callee(bcx, trans_fn_ref(bcx.ccx(), did, ExprId(ref_expr.id),
@@ -404,10 +407,13 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
     let def_id = inline::maybe_instantiate_inline(ccx, def_id);
 
     fn is_named_tuple_constructor(tcx: &ty::ctxt, def_id: DefId) -> bool {
-        if !def_id.is_local() { return false; }
+        let node_id = match tcx.map.as_local_node_id(def_id) {
+            Some(n) => n,
+            None => { return false; }
+        };
         let map_node = session::expect(
             &tcx.sess,
-            tcx.map.find(def_id.node),
+            tcx.map.find(node_id),
             || "local item should be in ast map".to_string());
 
         match map_node {
@@ -465,9 +471,9 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
 
     // Find the actual function pointer.
     let mut val = {
-        if def_id.is_local() {
+        if let Some(node_id) = ccx.tcx().map.as_local_node_id(def_id) {
             // Internal reference.
-            get_item_val(ccx, def_id.node)
+            get_item_val(ccx, node_id)
         } else {
             // External reference.
             trans_external_path(ccx, def_id, fn_type)
diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs
index d992f6eeab1..48fbbfffef6 100644
--- a/src/librustc_trans/trans/closure.rs
+++ b/src/librustc_trans/trans/closure.rs
@@ -44,8 +44,7 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     // Special case for small by-value selfs.
     let closure_id = bcx.tcx().map.local_def_id(bcx.fcx.id);
-    let self_type = self_type_for_closure(bcx.ccx(), closure_id,
-                                                  node_id_type(bcx, closure_id.node));
+    let self_type = self_type_for_closure(bcx.ccx(), closure_id, node_id_type(bcx, bcx.fcx.id));
     let kind = kind_for_closure(bcx.ccx(), closure_id);
     let llenv = if kind == ty::FnOnceClosureKind &&
             !arg_is_indirect(bcx.ccx(), self_type) {
@@ -70,7 +69,7 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     for (i, freevar) in freevars.iter().enumerate() {
         let upvar_id = ty::UpvarId { var_id: freevar.def.node_id(),
-                                     closure_expr_id: closure_id.node };
+                                     closure_expr_id: bcx.fcx.id };
         let upvar_capture = bcx.tcx().upvar_capture(upvar_id).unwrap();
         let mut upvar_ptr = StructGEP(bcx, llenv, i);
         let captured_by_ref = match upvar_capture {
@@ -80,21 +79,21 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 true
             }
         };
-        let def_id = freevar.def.def_id();
-        bcx.fcx.llupvars.borrow_mut().insert(def_id.node, upvar_ptr);
+        let node_id = freevar.def.node_id();
+        bcx.fcx.llupvars.borrow_mut().insert(node_id, upvar_ptr);
 
         if kind == ty::FnOnceClosureKind && !captured_by_ref {
             let hint = bcx.fcx.lldropflag_hints.borrow().hint_datum(upvar_id.var_id);
             bcx.fcx.schedule_drop_mem(arg_scope_id,
                                       upvar_ptr,
-                                      node_id_type(bcx, def_id.node),
+                                      node_id_type(bcx, node_id),
                                       hint)
         }
 
         if let Some(env_pointer_alloca) = env_pointer_alloca {
             debuginfo::create_captured_var_metadata(
                 bcx,
-                def_id.node,
+                node_id,
                 env_pointer_alloca,
                 i,
                 captured_by_ref,
@@ -133,6 +132,8 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                                    closure_id: DefId,
                                                    substs: &ty::ClosureSubsts<'tcx>)
                                                    -> ValueRef {
+    let closure_node_id = ccx.tcx().map.as_local_node_id(closure_id).unwrap();
+
     // Normalize type so differences in regions and typedefs don't cause
     // duplicate declarations
     let substs = ccx.tcx().erase_regions(substs);
@@ -147,7 +148,7 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         return llfn;
     }
 
-    let symbol = ccx.tcx().map.with_path(closure_id.node, |path| {
+    let symbol = ccx.tcx().map.with_path(closure_node_id, |path| {
         mangle_internal_name_by_path_and_seq(path, "closure")
     });
 
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 41d29e0dbd8..c7777c103e5 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -960,6 +960,9 @@ fn get_static_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                             did: DefId,
                             ty: Ty<'tcx>)
                             -> ValueRef {
-    if did.is_local() { return base::get_item_val(ccx, did.node) }
-    base::trans_external_path(ccx, did, ty)
+    if let Some(node_id) = ccx.tcx().map.as_local_node_id(did) {
+        base::get_item_val(ccx, node_id)
+    } else {
+        base::trans_external_path(ccx, did, ty)
+    }
 }
diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs
index 75dc67bd9b0..94c93a636a1 100644
--- a/src/librustc_trans/trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/trans/debuginfo/metadata.rs
@@ -324,8 +324,8 @@ impl<'tcx> TypeMap<'tcx> {
                                             output: &mut String) {
             // First, find out the 'real' def_id of the type. Items inlined from
             // other crates have to be mapped back to their source.
-            let source_def_id = if def_id.is_local() {
-                match cx.external_srcs().borrow().get(&def_id.node).cloned() {
+            let source_def_id = if let Some(node_id) = cx.tcx().map.as_local_node_id(def_id) {
+                match cx.external_srcs().borrow().get(&node_id).cloned() {
                     Some(source_def_id) => {
                         // The given def_id identifies the inlined copy of a
                         // type definition, let's take the source of the copy.
@@ -346,7 +346,7 @@ impl<'tcx> TypeMap<'tcx> {
 
             output.push_str(crate_hash.as_str());
             output.push_str("/");
-            output.push_str(&format!("{:x}", def_id.node));
+            output.push_str(&format!("{:x}", def_id.xxx_node));
 
             // Maybe check that there is no self type here.
 
diff --git a/src/librustc_trans/trans/debuginfo/utils.rs b/src/librustc_trans/trans/debuginfo/utils.rs
index 09d014a3382..276f9936ac5 100644
--- a/src/librustc_trans/trans/debuginfo/utils.rs
+++ b/src/librustc_trans/trans/debuginfo/utils.rs
@@ -99,12 +99,9 @@ pub fn assert_type_for_node_id(cx: &CrateContext,
 pub fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: DefId)
                                    -> (DIScope, Span) {
     let containing_scope = namespace_for_item(cx, def_id).scope;
-    let definition_span = if def_id.is_local() {
-        cx.tcx().map.span(def_id.node)
-    } else {
-        // For external items there is no span information
-        codemap::DUMMY_SP
-    };
+    let definition_span = cx.tcx().map.def_id_span(def_id, codemap::DUMMY_SP /* (1) */ );
+
+    // (1) For external items there is no span information
 
     (containing_scope, definition_span)
 }
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 722089e42f9..365caadeccb 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -923,13 +923,13 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let const_ty = expr_ty(bcx, ref_expr);
 
             // For external constants, we don't inline.
-            let val = if did.is_local() {
+            let val = if let Some(node_id) = bcx.tcx().map.as_local_node_id(did) {
                 // Case 1.
 
                 // The LLVM global has the type of its initializer,
                 // which may not be equal to the enum's type for
                 // non-C-like enums.
-                let val = base::get_item_val(bcx.ccx(), did.node);
+                let val = base::get_item_val(bcx.ccx(), node_id);
                 let pty = type_of::type_of(bcx.ccx(), const_ty).ptr_to();
                 PointerCast(bcx, val, pty)
             } else {
diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs
index bf5f20d72e3..67abca78c6e 100644
--- a/src/librustc_trans/trans/inline.rs
+++ b/src/librustc_trans/trans/inline.rs
@@ -193,7 +193,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
 
 pub fn get_local_instance(ccx: &CrateContext, fn_id: DefId)
     -> Option<DefId> {
-    if fn_id.is_local() {
+    if let Some(_) = ccx.tcx().map.as_local_node_id(fn_id) {
         Some(fn_id)
     } else {
         instantiate_inline(ccx, fn_id)
diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs
index df0323350fd..39f3a29c785 100644
--- a/src/librustc_trans/trans/monomorphize.rs
+++ b/src/librustc_trans/trans/monomorphize.rs
@@ -38,7 +38,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                 fn_id: DefId,
                                 psubsts: &'tcx subst::Substs<'tcx>,
                                 ref_id: Option<ast::NodeId>)
-    -> (ValueRef, Ty<'tcx>, bool) {
+                                -> (ValueRef, Ty<'tcx>, bool) {
     debug!("monomorphic_fn(\
             fn_id={:?}, \
             real_substs={:?}, \
@@ -49,6 +49,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     assert!(!psubsts.types.needs_infer() && !psubsts.types.has_param_types());
 
+    // we can only monomorphize things in this crate (or inlined into it)
+    let fn_node_id = ccx.tcx().map.as_local_node_id(fn_id).unwrap();
+
     let _icx = push_ctxt("monomorphic_fn");
 
     let hash_id = MonoId {
@@ -82,7 +85,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     let map_node = session::expect(
         ccx.sess(),
-        ccx.tcx().map.find(fn_id.node),
+        ccx.tcx().map.find(fn_node_id),
         || {
             format!("while monomorphizing {:?}, couldn't find it in \
                      the item map (may have attempted to monomorphize \
@@ -91,10 +94,10 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         });
 
     if let hir_map::NodeForeignItem(_) = map_node {
-        let abi = ccx.tcx().map.get_foreign_abi(fn_id.node);
+        let abi = ccx.tcx().map.get_foreign_abi(fn_node_id);
         if abi != abi::RustIntrinsic && abi != abi::PlatformIntrinsic {
             // Foreign externs don't have to be monomorphized.
-            return (get_item_val(ccx, fn_id.node), mono_ty, true);
+            return (get_item_val(ccx, fn_node_id), mono_ty, true);
         }
     }
 
@@ -111,7 +114,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         // recursively more than thirty times can probably safely be assumed
         // to be causing an infinite expansion.
         if depth > ccx.sess().recursion_limit.get() {
-            ccx.sess().span_fatal(ccx.tcx().map.span(fn_id.node),
+            ccx.sess().span_fatal(ccx.tcx().map.span(fn_node_id),
                 "reached the recursion limit during monomorphization");
         }
 
@@ -125,7 +128,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         mono_ty.hash(&mut state);
 
         hash = format!("h{}", state.finish());
-        ccx.tcx().map.with_path(fn_id.node, |path| {
+        ccx.tcx().map.with_path(fn_node_id, |path| {
             exported_name(path, &hash[..])
         })
     };
@@ -136,7 +139,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let mut hash_id = Some(hash_id);
     let mut mk_lldecl = |abi: abi::Abi| {
         let lldecl = if abi != abi::Rust {
-            foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s[..])
+            foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, &s)
         } else {
             // FIXME(nagisa): perhaps needs a more fine grained selection? See
             // setup_lldecl below.
@@ -178,10 +181,10 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                   if needs_body {
                       if abi != abi::Rust {
                           foreign::trans_rust_fn_with_foreign_abi(
-                              ccx, &**decl, &**body, &[], d, psubsts, fn_id.node,
+                              ccx, &**decl, &**body, &[], d, psubsts, fn_node_id,
                               Some(&hash[..]));
                       } else {
-                          trans_fn(ccx, &**decl, &**body, d, psubsts, fn_id.node, &[]);
+                          trans_fn(ccx, &**decl, &**body, d, psubsts, fn_node_id, &[]);
                       }
                   }
 
@@ -193,11 +196,11 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             }
         }
         hir_map::NodeVariant(v) => {
-            let variant = inlined_variant_def(ccx, fn_id.node);
+            let variant = inlined_variant_def(ccx, fn_node_id);
             assert_eq!(v.node.name, variant.name);
             let d = mk_lldecl(abi::Rust);
             attributes::inline(d, attributes::InlineAttr::Hint);
-            trans_enum_variant(ccx, fn_id.node, variant.disr_val, psubsts, d);
+            trans_enum_variant(ccx, fn_node_id, variant.disr_val, psubsts, d);
             d
         }
         hir_map::NodeImplItem(impl_item) => {
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index c424245facc..dd15c132560 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -48,7 +48,6 @@
 //! case but `&a` in the second.  Basically, defaults that appear inside
 //! an rptr (`&r.T`) use the region `r` that appears in the rptr.
 
-use metadata::cstore::LOCAL_CRATE;
 use middle::astconv_util::{prim_ty_to_ty, prohibit_type_params, prohibit_projection};
 use middle::const_eval::{self, ConstVal};
 use middle::const_eval::EvalHint::UncheckedExprHint;
@@ -174,7 +173,7 @@ pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &hir::Lifetime)
         Some(&rl::DefEarlyBoundRegion(space, index, id)) => {
             let def_id = tcx.map.local_def_id(id);
             ty::ReEarlyBound(ty::EarlyBoundRegion {
-                param_id: def_id,
+                def_id: def_id,
                 space: space,
                 index: index,
                 name: lifetime.name
@@ -1292,9 +1291,9 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
             }
         }
         (&ty::TyParam(_), def::DefSelfTy(Some(trait_did), None)) => {
-            assert_eq!(trait_did.krate, LOCAL_CRATE);
+            let trait_node_id = tcx.map.as_local_node_id(trait_did).unwrap();
             match find_bound_for_assoc_item(this,
-                                            trait_did.node,
+                                            trait_node_id,
                                             token::special_idents::type_self.name,
                                             assoc_name,
                                             span) {
@@ -1303,9 +1302,9 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
             }
         }
         (&ty::TyParam(_), def::DefTyParam(_, _, param_did, param_name)) => {
-            assert_eq!(param_did.krate, LOCAL_CRATE);
+            let param_node_id = tcx.map.as_local_node_id(param_did).unwrap();
             match find_bound_for_assoc_item(this,
-                                            param_did.node,
+                                            param_node_id,
                                             param_name,
                                             assoc_name,
                                             span) {
@@ -1326,10 +1325,10 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
     let trait_did = bound.0.def_id;
     let ty = this.projected_ty_from_poly_trait_ref(span, bound, assoc_name);
 
-    let item_did = if trait_did.is_local() {
+    let item_did = if let Some(trait_id) = tcx.map.as_local_node_id(trait_did) {
         // `ty::trait_items` used below requires information generated
         // by type collection, which may be in progress at this point.
-        match tcx.map.expect_item(trait_did.node).node {
+        match tcx.map.expect_item(trait_id).node {
             hir::ItemTrait(_, _, _, ref trait_items) => {
                 let item = trait_items.iter()
                                       .find(|i| i.name == assoc_name)
@@ -1508,11 +1507,12 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
             // we don't have the trait information around, which is just sad.
 
             if !base_segments.is_empty() {
+                let id_node = tcx.map.as_local_node_id(id).unwrap();
                 span_err!(tcx.sess,
                           span,
                           E0247,
                           "found module name used as a type: {}",
-                          tcx.map.node_to_string(id.node));
+                          tcx.map.node_to_user_string(id_node));
                 return this.tcx().types.err;
             }
 
@@ -1522,10 +1522,10 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
             prim_ty_to_ty(tcx, base_segments, prim_ty)
         }
         _ => {
-            let node = def.def_id().node;
+            let id_node = tcx.map.as_local_node_id(def.def_id()).unwrap();
             span_err!(tcx.sess, span, E0248,
                       "found value `{}` used as a type",
-                      tcx.map.path_to_string(node));
+                      tcx.map.path_to_string(id_node));
             return this.tcx().types.err;
         }
     }
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 6d8b757d167..c46f386af27 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -169,8 +169,8 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
 
     // Create a parameter environment that represents the implementation's
     // method.
-    let impl_param_env =
-        ty::ParameterEnvironment::for_item(tcx, impl_m.def_id.node);
+    let impl_m_node_id = tcx.map.as_local_node_id(impl_m.def_id).unwrap();
+    let impl_param_env = ty::ParameterEnvironment::for_item(tcx, impl_m_node_id);
 
     // Create mapping from impl to skolemized.
     let impl_to_skol_substs = &impl_param_env.free_substs;
@@ -428,8 +428,8 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>,
 
     // Create a parameter environment that represents the implementation's
     // method.
-    let impl_param_env =
-        ty::ParameterEnvironment::for_item(tcx, impl_c.def_id.node);
+    let impl_c_node_id = tcx.map.as_local_node_id(impl_c.def_id).unwrap();
+    let impl_param_env = ty::ParameterEnvironment::for_item(tcx, impl_c_node_id);
 
     // Create mapping from impl to skolemized.
     let impl_to_skol_substs = &impl_param_env.free_substs;
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index d847f481142..870a81e510e 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -10,7 +10,6 @@
 
 use check::regionck::{self, Rcx};
 
-use metadata::cstore::LOCAL_CRATE;
 use middle::def_id::DefId;
 use middle::free_region::FreeRegionMap;
 use middle::infer;
@@ -78,11 +77,12 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
     drop_impl_ty: &ty::Ty<'tcx>,
     self_type_did: DefId) -> Result<(), ()>
 {
-    assert!(drop_impl_did.is_local() && self_type_did.is_local());
+    let drop_impl_node_id = tcx.map.as_local_node_id(drop_impl_did).unwrap();
+    let self_type_node_id = tcx.map.as_local_node_id(self_type_did).unwrap();
 
     // check that the impl type can be made to match the trait type.
 
-    let impl_param_env = ty::ParameterEnvironment::for_item(tcx, self_type_did.node);
+    let impl_param_env = ty::ParameterEnvironment::for_item(tcx, self_type_node_id);
     let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(impl_param_env), true);
 
     let named_type = tcx.lookup_item_type(self_type_did).ty;
@@ -97,7 +97,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
                                    named_type, fresh_impl_self_ty) {
         span_err!(tcx.sess, drop_impl_span, E0366,
                   "Implementations of Drop cannot be specialized");
-        let item_span = tcx.map.span(self_type_did.node);
+        let item_span = tcx.map.span(self_type_node_id);
         tcx.sess.span_note(item_span,
                            "Use same sequence of generic type and region \
                             parameters that is on the struct/enum definition");
@@ -111,7 +111,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
     }
 
     let free_regions = FreeRegionMap::new();
-    infcx.resolve_regions_and_report_errors(&free_regions, drop_impl_did.node);
+    infcx.resolve_regions_and_report_errors(&free_regions, drop_impl_node_id);
     Ok(())
 }
 
@@ -159,7 +159,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
     // absent. So we report an error that the Drop impl injected a
     // predicate that is not present on the struct definition.
 
-    assert_eq!(self_type_did.krate, LOCAL_CRATE);
+    let self_type_node_id = tcx.map.as_local_node_id(self_type_did).unwrap();
 
     let drop_impl_span = tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP);
 
@@ -196,7 +196,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
         // repeated `contains` calls.
 
         if !assumptions_in_impl_context.contains(&predicate) {
-            let item_span = tcx.map.span(self_type_did.node);
+            let item_span = tcx.map.span(self_type_node_id);
             span_err!(tcx.sess, drop_impl_span, E0367,
                       "The requirement `{}` is added only by the Drop impl.", predicate);
             tcx.sess.span_note(item_span,
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index caa6b226d1b..e10175c81aa 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -365,13 +365,11 @@ impl PartialOrd for TraitInfo {
 }
 impl Ord for TraitInfo {
     fn cmp(&self, other: &TraitInfo) -> Ordering {
-        // accessible traits are more important/relevant than
-        // inaccessible ones, local crates are more important than
-        // remote ones (local: cnum == 0), and NodeIds just for
-        // totality.
+        // local crates are more important than remote ones (local:
+        // cnum == 0), and otherwise we throw in the defid for totality
 
-        let lhs = (other.def_id.krate, other.def_id.node);
-        let rhs = (self.def_id.krate, self.def_id.node);
+        let lhs = (other.def_id.krate, other.def_id);
+        let rhs = (self.def_id.krate, self.def_id);
         lhs.cmp(&rhs)
     }
 }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 7f4b1095cb5..7d4101fa243 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4248,7 +4248,8 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                 Some(i) => {
                     span_err!(ccx.tcx.sess, v.span, E0081,
                         "discriminant value `{}` already exists", disr_vals[i]);
-                    span_note!(ccx.tcx.sess, ccx.tcx.map.span(variants[i].did.node),
+                    let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
+                    span_note!(ccx.tcx.sess, ccx.tcx.map.span(variant_i_node_id),
                         "conflicting discriminant here")
                 }
                 None => {}
@@ -4275,8 +4276,8 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         }
     }
 
-    let hint = *ccx.tcx.lookup_repr_hints(DefId { krate: LOCAL_CRATE, node: id })
-        .get(0).unwrap_or(&attr::ReprAny);
+    let def_id = ccx.tcx.map.local_def_id(id);
+    let hint = *ccx.tcx.lookup_repr_hints(def_id).get(0).unwrap_or(&attr::ReprAny);
 
     if hint != attr::ReprAny && vs.len() <= 1 {
         if vs.len() == 1 {
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index 590b7e50e94..0024b51ae0f 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -235,16 +235,16 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
         tcx.with_freevars(closure_id, |freevars| {
             freevars.iter()
                     .map(|freevar| {
-                        let freevar_def_id = freevar.def.def_id();
-                        let freevar_ty = self.fcx.node_ty(freevar_def_id.node);
+                        let freevar_node_id = freevar.def.node_id();
+                        let freevar_ty = self.fcx.node_ty(freevar_node_id);
                         let upvar_id = ty::UpvarId {
-                            var_id: freevar_def_id.node,
+                            var_id: freevar_node_id,
                             closure_expr_id: closure_id
                         };
                         let capture = self.fcx.infcx().upvar_capture(upvar_id).unwrap();
 
-                        debug!("freevar_def_id={:?} freevar_ty={:?} capture={:?}",
-                               freevar_def_id, freevar_ty, capture);
+                        debug!("freevar_node_id={:?} freevar_ty={:?} capture={:?}",
+                               freevar_node_id, freevar_ty, capture);
 
                         match capture {
                             ty::UpvarCapture::ByValue => freevar_ty,
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 68c0f130c20..16884e76a8e 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -388,8 +388,8 @@ impl ResolveReason {
                 tcx.expr_span(upvar_id.closure_expr_id)
             }
             ResolvingClosure(did) => {
-                if did.is_local() {
-                    tcx.expr_span(did.node)
+                if let Some(node_id) = tcx.map.as_local_node_id(did) {
+                    tcx.expr_span(node_id)
                 } else {
                     DUMMY_SP
                 }
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index ddb11c910b1..b3ec10a8941 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -16,7 +16,6 @@
 // mappings. That mapping code resides here.
 
 
-use metadata::cstore::LOCAL_CRATE;
 use middle::def_id::DefId;
 use middle::lang_items::UnsizeTraitLangItem;
 use middle::subst::{self, Subst};
@@ -247,17 +246,15 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
                 }
                 _ => {
                     // Destructors only work on nominal types.
-                    if impl_did.is_local() {
-                        {
-                            match tcx.map.find(impl_did.node) {
-                                Some(hir_map::NodeItem(item)) => {
-                                    span_err!(tcx.sess, item.span, E0120,
-                                        "the Drop trait may only be implemented on structures");
-                                }
-                                _ => {
-                                    tcx.sess.bug("didn't find impl in ast \
-                                                  map");
-                                }
+                    if let Some(impl_node_id) = tcx.map.as_local_node_id(impl_did) {
+                        match tcx.map.find(impl_node_id) {
+                            Some(hir_map::NodeItem(item)) => {
+                                span_err!(tcx.sess, item.span, E0120,
+                                          "the Drop trait may only be implemented on structures");
+                            }
+                            _ => {
+                                tcx.sess.bug("didn't find impl in ast \
+                                              map");
                             }
                         }
                     } else {
@@ -283,18 +280,20 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             debug!("check_implementations_of_copy: impl_did={:?}",
                    impl_did);
 
-            if impl_did.krate != LOCAL_CRATE {
+            let impl_node_id = if let Some(n) = tcx.map.as_local_node_id(impl_did) {
+                n
+            } else {
                 debug!("check_implementations_of_copy(): impl not in this \
                         crate");
                 return
-            }
+            };
 
             let self_type = tcx.lookup_item_type(impl_did);
             debug!("check_implementations_of_copy: self_type={:?} (bound)",
                    self_type);
 
-            let span = tcx.map.span(impl_did.node);
-            let param_env = ParameterEnvironment::for_item(tcx, impl_did.node);
+            let span = tcx.map.span(impl_node_id);
+            let param_env = ParameterEnvironment::for_item(tcx, impl_node_id);
             let self_type = self_type.ty.subst(tcx, &param_env.free_substs);
             assert!(!self_type.has_escaping_regions());
 
@@ -352,11 +351,13 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             debug!("check_implementations_of_coerce_unsized: impl_did={:?}",
                    impl_did);
 
-            if impl_did.krate != LOCAL_CRATE {
+            let impl_node_id = if let Some(n) = tcx.map.as_local_node_id(impl_did) {
+                n
+            } else {
                 debug!("check_implementations_of_coerce_unsized(): impl not \
                         in this crate");
                 return;
-            }
+            };
 
             let source = tcx.lookup_item_type(impl_did).ty;
             let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap();
@@ -364,8 +365,8 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)",
                    source, target);
 
-            let span = tcx.map.span(impl_did.node);
-            let param_env = ParameterEnvironment::for_item(tcx, impl_did.node);
+            let span = tcx.map.span(impl_node_id);
+            let param_env = ParameterEnvironment::for_item(tcx, impl_node_id);
             let source = source.subst(tcx, &param_env.free_substs);
             let target = target.subst(tcx, &param_env.free_substs);
             assert!(!source.has_escaping_regions());
@@ -465,7 +466,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
 
             // Register an obligation for `A: Trait<B>`.
-            let cause = traits::ObligationCause::misc(span, impl_did.node);
+            let cause = traits::ObligationCause::misc(span, impl_node_id);
             let predicate = traits::predicate_for_trait_def(tcx, cause, trait_def_id,
                                                             0, source, vec![target]);
             fulfill_cx.register_predicate_obligation(&infcx, predicate);
@@ -479,7 +480,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             let mut free_regions = FreeRegionMap::new();
             free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment
                                                                         .caller_bounds);
-            infcx.resolve_regions_and_report_errors(&free_regions, impl_did.node);
+            infcx.resolve_regions_and_report_errors(&free_regions, impl_node_id);
 
             if let Some(kind) = kind {
                 tcx.custom_coerce_unsized_kinds.borrow_mut().insert(impl_did, kind);
diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
index a2c8e8fd131..706f28f9fe4 100644
--- a/src/librustc_typeck/coherence/overlap.rs
+++ b/src/librustc_typeck/coherence/overlap.rs
@@ -112,7 +112,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
             }
         } else if impl2_def_id.krate != LOCAL_CRATE {
             Some((impl1_def_id, impl2_def_id))
-        } else if impl1_def_id.node < impl2_def_id.node {
+        } else if impl1_def_id < impl2_def_id {
             Some((impl1_def_id, impl2_def_id))
         } else {
             Some((impl2_def_id, impl1_def_id))
@@ -165,8 +165,8 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
     }
 
     fn span_of_impl(&self, impl_did: DefId) -> Span {
-        assert_eq!(impl_did.krate, LOCAL_CRATE);
-        self.tcx.map.span(impl_did.node)
+        let node_id = self.tcx.map.as_local_node_id(impl_did).unwrap();
+        self.tcx.map.span(node_id)
     }
 }
 
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index e24d3f340b6..39805bfc8a3 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -65,7 +65,6 @@ There are some shortcomings in this design:
 */
 
 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
-use metadata::cstore::LOCAL_CRATE;
 use middle::def;
 use middle::def_id::DefId;
 use constrained_type_params as ctp;
@@ -317,16 +316,16 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
     {
         let tcx = self.tcx;
 
-        if trait_id.krate != LOCAL_CRATE {
-            return tcx.lookup_trait_def(trait_id)
-        }
-
-        let item = match tcx.map.get(trait_id.node) {
-            hir_map::NodeItem(item) => item,
-            _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
-        };
+        if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
+            let item = match tcx.map.get(trait_id) {
+                hir_map::NodeItem(item) => item,
+                _ => tcx.sess.bug(&format!("get_trait_def({:?}): not an item", trait_id))
+            };
 
-        trait_def_of_item(self, &*item)
+            trait_def_of_item(self, &*item)
+        } else {
+            tcx.lookup_trait_def(trait_id)
+        }
     }
 
     /// Ensure that the (transitive) super predicates for
@@ -403,8 +402,8 @@ impl<'a, 'tcx> AstConv<'tcx> for ItemCtxt<'a, 'tcx> {
                                            assoc_name: ast::Name)
                                            -> bool
     {
-        if trait_def_id.is_local() {
-            trait_defines_associated_type_named(self.ccx, trait_def_id.node, assoc_name)
+        if let Some(trait_id) = self.tcx().map.as_local_node_id(trait_def_id) {
+            trait_defines_associated_type_named(self.ccx, trait_id, assoc_name)
         } else {
             let trait_def = self.tcx().lookup_trait_def(trait_def_id);
             trait_def.associated_type_names.contains(&assoc_name)
@@ -558,8 +557,8 @@ fn is_param<'tcx>(tcx: &ty::ctxt<'tcx>,
     if let hir::TyPath(None, _) = ast_ty.node {
         let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap();
         match path_res.base_def {
-            def::DefSelfTy(Some(def_id), None) => { // XXX
-                path_res.depth == 0 && def_id.node == param_id
+            def::DefSelfTy(Some(def_id), None) => {
+                path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
             }
             def::DefTyParam(_, _, def_id, _) => {
                 path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id)
@@ -1271,19 +1270,19 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
 
     debug!("ensure_super_predicates_step(trait_def_id={:?})", trait_def_id);
 
-    if trait_def_id.krate != LOCAL_CRATE {
+    let trait_node_id = if let Some(n) = tcx.map.as_local_node_id(trait_def_id) {
+        n
+    } else {
         // If this trait comes from an external crate, then all of the
         // supertraits it may depend on also must come from external
         // crates, and hence all of them already have their
         // super-predicates "converted" (and available from crate
         // meta-data), so there is no need to transitively test them.
         return Vec::new();
-    }
+    };
 
     let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
     let superpredicates = superpredicates.unwrap_or_else(|| {
-        let trait_node_id = trait_def_id.node;
-
         let item = match ccx.tcx.map.get(trait_node_id) {
             hir_map::NodeItem(item) => item,
             _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
@@ -1412,15 +1411,12 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             generics.lifetimes
                     .iter()
                     .enumerate()
-                    .map(|(i, def)| {
-                        let def_id = tcx.map.local_def_id(def.lifetime.id);
-                        ty::ReEarlyBound(ty::EarlyBoundRegion {
-                            param_id: def_id,
-                            space: TypeSpace,
-                            index: i as u32,
-                            name: def.lifetime.name
-                        })
-                    })
+                    .map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
+                        def_id: tcx.map.local_def_id(def.lifetime.id),
+                        space: TypeSpace,
+                        index: i as u32,
+                        name: def.lifetime.name
+                    }))
                     .collect();
 
         // Start with the generics in the type parameters...
@@ -1540,23 +1536,23 @@ fn type_scheme_of_def_id<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                   def_id: DefId)
                                   -> ty::TypeScheme<'tcx>
 {
-    if def_id.krate != LOCAL_CRATE {
-        return ccx.tcx.lookup_item_type(def_id);
-    }
-
-    match ccx.tcx.map.find(def_id.node) {
-        Some(hir_map::NodeItem(item)) => {
-            type_scheme_of_item(ccx, &*item)
-        }
-        Some(hir_map::NodeForeignItem(foreign_item)) => {
-            let abi = ccx.tcx.map.get_foreign_abi(def_id.node);
-            type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
-        }
-        x => {
-            ccx.tcx.sess.bug(&format!("unexpected sort of node \
-                                            in get_item_type_scheme(): {:?}",
-                                       x));
+    if let Some(node_id) = ccx.tcx.map.as_local_node_id(def_id) {
+        match ccx.tcx.map.find(node_id) {
+            Some(hir_map::NodeItem(item)) => {
+                type_scheme_of_item(ccx, &*item)
+            }
+            Some(hir_map::NodeForeignItem(foreign_item)) => {
+                let abi = ccx.tcx.map.get_foreign_abi(node_id);
+                type_scheme_of_foreign_item(ccx, &*foreign_item, abi)
+            }
+            x => {
+                ccx.tcx.sess.bug(&format!("unexpected sort of node \
+                                           in get_item_type_scheme(): {:?}",
+                                          x));
+            }
         }
+    } else {
+        ccx.tcx.lookup_item_type(def_id)
     }
 }
 
@@ -1894,7 +1890,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         let def_id = tcx.map.local_def_id(param.lifetime.id);
         let region =
             ty::ReEarlyBound(ty::EarlyBoundRegion {
-                param_id: def_id,
+                def_id: def_id,
                 space: space,
                 index: index,
                 name: param.lifetime.name
@@ -2392,9 +2388,10 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
         tcx.fold_regions(value, &mut false, |region, _| {
             match region {
                 ty::ReEarlyBound(data) => {
-                    let def_id = data.param_id;
-                    ty::ReFree(ty::FreeRegion { scope: scope,
-                                                bound_region: ty::BrNamed(def_id, data.name) })
+                    ty::ReFree(ty::FreeRegion {
+                        scope: scope,
+                        bound_region: ty::BrNamed(data.def_id, data.name)
+                    })
                 }
                 _ => region
             }
@@ -2453,7 +2450,7 @@ fn enforce_impl_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
 
     for (index, lifetime_def) in ast_generics.lifetimes.iter().enumerate() {
         let def_id = tcx.map.local_def_id(lifetime_def.lifetime.id);
-        let region = ty::EarlyBoundRegion { param_id: def_id,
+        let region = ty::EarlyBoundRegion { def_id: def_id,
                                             space: TypeSpace,
                                             index: index as u32,
                                             name: lifetime_def.lifetime.name };
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index 86a97f305aa..8152e685d8d 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -266,7 +266,6 @@ use self::ParamKind::*;
 
 use arena;
 use arena::TypedArena;
-use metadata::cstore::LOCAL_CRATE;
 use middle::def_id::DefId;
 use middle::resolve_lifetime as rl;
 use middle::subst;
@@ -404,10 +403,10 @@ fn lang_items(tcx: &ty::ctxt) -> Vec<(ast::NodeId,Vec<ty::Variance>)> {
 
         ];
 
-    all.into_iter()
+    all.into_iter() // iterating over (Option<DefId>, Variance)
        .filter(|&(ref d,_)| d.is_some())
-       .filter(|&(ref d,_)| d.as_ref().unwrap().is_local())
-       .map(|(d, v)| (d.unwrap().node, v))
+       .map(|(d, v)| (d.unwrap(), v)) // (DefId, Variance)
+       .filter_map(|(d, v)| tcx.map.as_local_node_id(d).map(|n| (n, v))) // (NodeId, Variance)
        .collect()
 }
 
@@ -741,11 +740,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                          -> VarianceTermPtr<'a> {
         assert_eq!(param_def_id.krate, item_def_id.krate);
 
-        if param_def_id.is_local() {
+        if let Some(param_node_id) = self.tcx().map.as_local_node_id(param_def_id) {
             // Parameter on an item defined within current crate:
             // variance not yet inferred, so return a symbolic
             // variance.
-            let InferredIndex(index) = self.inferred_index(param_def_id.node);
+            let InferredIndex(index) = self.inferred_index(param_node_id);
             self.terms_cx.inferred_infos[index].term
         } else {
             // Parameter on an item defined within another crate:
@@ -924,8 +923,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
             ty::TyParam(ref data) => {
                 let def_id = generics.types.get(data.space, data.idx as usize).def_id;
-                assert_eq!(def_id.krate, LOCAL_CRATE);
-                match self.terms_cx.inferred_map.get(&def_id.node) {
+                let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
+                match self.terms_cx.inferred_map.get(&node_id) {
                     Some(&index) => {
                         self.add_constraint(index, variance);
                     }
@@ -1013,7 +1012,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                                    variance: VarianceTermPtr<'a>) {
         match region {
             ty::ReEarlyBound(ref data) => {
-                let node_id = self.tcx().map.as_local_node_id(data.param_id).unwrap();
+                let node_id = self.tcx().map.as_local_node_id(data.def_id).unwrap();
                 if self.is_to_be_inferred(node_id) {
                     let index = self.inferred_index(node_id);
                     self.add_constraint(index, variance);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index e6580a2c037..344008b904e 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -36,7 +36,6 @@ use syntax::ptr::P;
 
 use rustc_trans::back::link;
 use rustc::metadata::cstore;
-use rustc::metadata::cstore::LOCAL_CRATE;
 use rustc::metadata::csearch;
 use rustc::metadata::decoder;
 use rustc::middle::def;
@@ -496,7 +495,7 @@ impl Clean<TyParam> for hir::TyParam {
     fn clean(&self, cx: &DocContext) -> TyParam {
         TyParam {
             name: self.name.clean(cx),
-            did: DefId { krate: LOCAL_CRATE, node: self.id },
+            did: cx.map.local_def_id(self.id),
             bounds: self.bounds.clean(cx),
             default: self.default.clean(cx),
         }
@@ -1138,10 +1137,10 @@ impl<'tcx> Clean<Type> for ty::FnOutput<'tcx> {
 impl<'a, 'tcx> Clean<FnDecl> for (DefId, &'a ty::PolyFnSig<'tcx>) {
     fn clean(&self, cx: &DocContext) -> FnDecl {
         let (did, sig) = *self;
-        let mut names = if did.node != 0 {
-            csearch::get_method_arg_names(&cx.tcx().sess.cstore, did).into_iter()
+        let mut names = if let Some(_) = cx.map.as_local_node_id(did) {
+            vec![].into_iter()
         } else {
-            Vec::new().into_iter()
+            csearch::get_method_arg_names(&cx.tcx().sess.cstore, did).into_iter()
         }.peekable();
         if names.peek().map(|s| &**s) == Some("self") {
             let _ = names.next();
@@ -1745,7 +1744,7 @@ impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
         let (name, attrs) = if self.name == unnamed_field.name {
             (None, None)
         } else {
-            (Some(self.name), Some(attr_map.get(&self.did.node).unwrap()))
+            (Some(self.name), Some(attr_map.get(&self.did.xxx_node).unwrap()))
         };
 
         Item {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 8bc832a68db..c84a7e7c560 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -13,9 +13,10 @@ use rustc_lint;
 use rustc_driver::{driver, target_features};
 use rustc::session::{self, config};
 use rustc::middle::def_id::DefId;
-use rustc::middle::{privacy, ty};
+use rustc::middle::ty;
 use rustc::front::map as hir_map;
 use rustc::lint;
+use rustc::util::nodemap::DefIdSet;
 use rustc_trans::back::link;
 use rustc_resolve as resolve;
 use rustc_front::lowering::lower_crate;
@@ -76,8 +77,8 @@ impl<'b, 'tcx> DocContext<'b, 'tcx> {
 }
 
 pub struct CrateAnalysis {
-    pub exported_items: privacy::ExportedItems,
-    pub public_items: privacy::PublicItems,
+    pub exported_items: DefIdSet,
+    pub public_items: DefIdSet,
     pub external_paths: ExternalPaths,
     pub external_typarams: RefCell<Option<HashMap<DefId, String>>>,
     pub inlined: RefCell<Option<HashSet<DefId>>>,
@@ -146,6 +147,17 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
                                         |tcx, analysis| {
         let ty::CrateAnalysis { exported_items, public_items, .. } = analysis;
 
+        // Convert from a NodeId set to a DefId set since we don't always have easy access
+        // to the map from defid -> nodeid
+        let exported_items: DefIdSet =
+            exported_items.into_iter()
+                          .map(|n| tcx.map.local_def_id(n))
+                          .collect();
+        let public_items: DefIdSet =
+            public_items.into_iter()
+                        .map(|n| tcx.map.local_def_id(n))
+                        .collect();
+
         let ctxt = DocContext {
             map: &tcx.map,
             maybe_typed: Typed(tcx),
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index f1c3e97a900..6937dbf255e 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -387,7 +387,7 @@ fn primitive_link(f: &mut fmt::Formatter,
         Some(&cnum) => {
             let path = &m.paths[&DefId {
                 krate: cnum,
-                node: ast::CRATE_NODE_ID,
+                xxx_node: ast::CRATE_NODE_ID,
             }];
             let loc = match m.extern_locations[&cnum] {
                 (_, render::Remote(ref s)) => Some(s.to_string()),
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c392e75ebf9..708c8f634f5 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -54,8 +54,8 @@ use externalfiles::ExternalHtml;
 use serialize::json::{self, ToJson};
 use syntax::{abi, ast, attr};
 use rustc::metadata::cstore::LOCAL_CRATE;
-use rustc::middle::def_id::{DefId, LOCAL_CRATE};
-use rustc::util::nodemap::NodeSet;
+use rustc::middle::def_id::DefId;
+use rustc::util::nodemap::DefIdSet;
 use rustc_front::hir;
 
 use clean::{self, SelfTy};
@@ -206,7 +206,7 @@ pub struct Cache {
     search_index: Vec<IndexItem>,
     privmod: bool,
     remove_priv: bool,
-    public_items: NodeSet,
+    public_items: DefIdSet,
     deref_trait_did: Option<DefId>,
 
     // In rare case where a structure is defined in one module but implemented
@@ -378,7 +378,7 @@ pub fn run(mut krate: clean::Crate,
     let analysis = ::ANALYSISKEY.with(|a| a.clone());
     let analysis = analysis.borrow();
     let public_items = analysis.as_ref().map(|a| a.public_items.clone());
-    let public_items = public_items.unwrap_or(NodeSet());
+    let public_items = public_items.unwrap_or(DefIdSet());
     let paths: HashMap<DefId, (Vec<String>, ItemType)> =
       analysis.as_ref().map(|a| {
         let paths = a.external_paths.borrow_mut().take().unwrap();
@@ -413,7 +413,7 @@ pub fn run(mut krate: clean::Crate,
     for &(n, ref e) in &krate.externs {
         cache.extern_locations.insert(n, (e.name.clone(),
                                           extern_location(e, &cx.dst)));
-        let did = DefId { krate: n, node: ast::CRATE_NODE_ID };
+        let did = DefId { krate: n, xxx_node: ast::CRATE_NODE_ID };
         cache.paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
     }
 
@@ -994,10 +994,11 @@ impl DocFolder for Cache {
                 // `public_items` map, so we can skip inserting into the
                 // paths map if there was already an entry present and we're
                 // not a public item.
-                let id = item.def_id.node;
-                if !self.paths.contains_key(&item.def_id) ||
-                   !item.def_id.is_local() ||
-                   self.public_items.contains(&id) {
+                if
+                    !self.paths.contains_key(&item.def_id) ||
+                    !item.def_id.is_local() ||
+                    self.public_items.contains(&item.def_id)
+                {
                     self.paths.insert(item.def_id,
                                       (self.stack.clone(), shortty(&item)));
                 }
@@ -1079,7 +1080,7 @@ impl DocFolder for Cache {
                                 t.primitive_type().and_then(|t| {
                                     self.primitive_locations.get(&t).map(|n| {
                                         let id = t.to_node_id();
-                                        DefId { krate: *n, node: id }
+                                        DefId { krate: *n, xxx_node: id }
                                     })
                                 })
                             }
@@ -1420,7 +1421,7 @@ impl<'a> Item<'a> {
                          root = root,
                          path = path[..path.len() - 1].join("/"),
                          file = item_path(self.item),
-                         goto = self.item.def_id.node))
+                         goto = self.item.def_id.xxx_node))
         }
     }
 }
@@ -1480,7 +1481,7 @@ impl<'a> fmt::Display for Item<'a> {
                 Some(l) => {
                     try!(write!(fmt, "<a id='src-{}' class='srclink' \
                                        href='{}' title='{}'>[src]</a>",
-                                self.item.def_id.node, l, "goto source code"));
+                                self.item.def_id.xxx_node, l, "goto source code"));
                 }
                 None => {}
             }
@@ -2336,7 +2337,7 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl) -> f
         _ => {
             if let Some(prim) = target.primitive_type() {
                 if let Some(c) = cache().primitive_locations.get(&prim) {
-                    let did = DefId { krate: *c, node: prim.to_node_id() };
+                    let did = DefId { krate: *c, xxx_node: prim.to_node_id() };
                     try!(render_assoc_items(w, cx, did, what));
                 }
             }
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index 8a57a50bdea..e7e38220825 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -8,12 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::collections::HashSet;
-use rustc::util::nodemap::NodeSet;
+use rustc::util::nodemap::DefIdSet;
 use std::cmp;
 use std::string::String;
 use std::usize;
-use syntax::ast;
 use rustc_front::hir;
 
 use clean;
@@ -24,18 +22,18 @@ use fold::DocFolder;
 
 /// Strip items marked `#[doc(hidden)]`
 pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
-    let mut stripped = HashSet::new();
+    let mut stripped = DefIdSet();
 
     // strip all #[doc(hidden)] items
     let krate = {
         struct Stripper<'a> {
-            stripped: &'a mut HashSet<ast::NodeId>
+            stripped: &'a mut DefIdSet
         };
         impl<'a> fold::DocFolder for Stripper<'a> {
             fn fold_item(&mut self, i: Item) -> Option<Item> {
                 if i.is_hidden_from_doc() {
                     debug!("found one in strip_hidden; removing");
-                    self.stripped.insert(i.def_id.node);
+                    self.stripped.insert(i.def_id);
 
                     // use a dedicated hidden item for given item type if any
                     match i.inner {
@@ -61,7 +59,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
     // strip any traits implemented on stripped items
     let krate = {
         struct ImplStripper<'a> {
-            stripped: &'a mut HashSet<ast::NodeId>
+            stripped: &'a mut DefIdSet
         };
         impl<'a> fold::DocFolder for ImplStripper<'a> {
             fn fold_item(&mut self, i: Item) -> Option<Item> {
@@ -70,12 +68,12 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
                            ref trait_, ..
                 }) = i.inner {
                     // Impls for stripped types don't need to exist
-                    if self.stripped.contains(&did.node) {
+                    if self.stripped.contains(&did) {
                         return None;
                     }
                     // Impls of stripped traits also don't need to exist
                     if let Some(clean::ResolvedPath { did, .. }) = *trait_ {
-                        if self.stripped.contains(&did.node) {
+                        if self.stripped.contains(&did) {
                             return None;
                         }
                     }
@@ -94,7 +92,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
 /// crate, specified by the `xcrate` flag.
 pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
     // This stripper collects all *retained* nodes.
-    let mut retained = HashSet::new();
+    let mut retained = DefIdSet();
     let analysis = super::ANALYSISKEY.with(|a| a.clone());
     let analysis = analysis.borrow();
     let analysis = analysis.as_ref().unwrap();
@@ -118,8 +116,8 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
 }
 
 struct Stripper<'a> {
-    retained: &'a mut HashSet<ast::NodeId>,
-    exported_items: &'a NodeSet,
+    retained: &'a mut DefIdSet,
+    exported_items: &'a DefIdSet,
 }
 
 impl<'a> fold::DocFolder for Stripper<'a> {
@@ -132,7 +130,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
             clean::VariantItem(..) | clean::MethodItem(..) |
             clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) => {
                 if i.def_id.is_local() {
-                    if !self.exported_items.contains(&i.def_id.node) {
+                    if !self.exported_items.contains(&i.def_id) {
                         return None;
                     }
                     // Traits are in exported_items even when they're totally private.
@@ -143,8 +141,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
             }
 
             clean::ConstantItem(..) => {
-                if i.def_id.is_local() &&
-                   !self.exported_items.contains(&i.def_id.node) {
+                if i.def_id.is_local() && !self.exported_items.contains(&i.def_id) {
                     return None;
                 }
             }
@@ -171,8 +168,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
             clean::ImplItem(clean::Impl{
                 for_: clean::ResolvedPath{ did, .. }, ..
             }) => {
-                if did.is_local() &&
-                   !self.exported_items.contains(&did.node) {
+                if did.is_local() && !self.exported_items.contains(&did) {
                     return None;
                 }
             }
@@ -205,7 +201,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
         };
 
         let i = if fastreturn {
-            self.retained.insert(i.def_id.node);
+            self.retained.insert(i.def_id);
             return Some(i);
         } else {
             self.fold_item_recur(i)
@@ -220,7 +216,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
                            i.doc_value().is_none() => None,
                     clean::ImplItem(ref i) if i.items.is_empty() => None,
                     _ => {
-                        self.retained.insert(i.def_id.node);
+                        self.retained.insert(i.def_id);
                         Some(i)
                     }
                 }
@@ -231,14 +227,13 @@ impl<'a> fold::DocFolder for Stripper<'a> {
 }
 
 // This stripper discards all private impls of traits
-struct ImplStripper<'a>(&'a HashSet<ast::NodeId>);
+struct ImplStripper<'a>(&'a DefIdSet);
 impl<'a> fold::DocFolder for ImplStripper<'a> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         if let clean::ImplItem(ref imp) = i.inner {
             match imp.trait_ {
                 Some(clean::ResolvedPath{ did, .. }) => {
-                    let ImplStripper(s) = *self;
-                    if did.is_local() && !s.contains(&did.node) {
+                    if did.is_local() && !self.0.contains(&did) {
                         return None;
                     }
                 }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index f9c8f2a0b8d..9972ede8b8f 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -205,16 +205,18 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             None => return false
         };
         let def = tcx.def_map.borrow()[&id].def_id();
-        if !def.is_local() { return false }
+        let def_node_id = match tcx.map.as_local_node_id(def) {
+            Some(n) => n, None => return false
+        };
         let analysis = match self.analysis {
             Some(analysis) => analysis, None => return false
         };
-        if !please_inline && analysis.public_items.contains(&def.node) {
+        if !please_inline && analysis.public_items.contains(&def) {
             return false
         }
-        if !self.view_item_stack.insert(def.node) { return false }
+        if !self.view_item_stack.insert(def_node_id) { return false }
 
-        let ret = match tcx.map.get(def.node) {
+        let ret = match tcx.map.get(def_node_id) {
             hir_map::NodeItem(it) => {
                 if glob {
                     let prev = mem::replace(&mut self.inlining_from_glob, true);
@@ -235,7 +237,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             }
             _ => false,
         };
-        self.view_item_stack.remove(&id);
+        self.view_item_stack.remove(&def_node_id);
         return ret;
     }