From 39a0969e64c06e7c6e5447b5633b02e4e4e931df Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Wed, 7 Nov 2018 10:08:41 +0100
Subject: [PATCH 1/7] Make `NodeId` a `newtype_index` to enable niche
 optimizations

---
 src/librustc/hir/intravisit.rs           |  5 +--
 src/librustc/hir/map/hir_id_validator.rs |  2 +-
 src/librustc/session/mod.rs              |  4 +-
 src/librustc_driver/pretty.rs            |  2 +-
 src/librustc_resolve/resolve_imports.rs  |  2 +-
 src/libsyntax/ast.rs                     | 54 ++++++++----------------
 src/libsyntax/lib.rs                     |  3 +-
 7 files changed, 26 insertions(+), 46 deletions(-)

diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index dcc0f8545e5d7..d9963f23a1593 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -49,7 +49,6 @@ use hir::map::{self, Map};
 use super::itemlikevisit::DeepVisitor;
 
 use std::cmp;
-use std::u32;
 
 #[derive(Copy, Clone)]
 pub enum FnKind<'a> {
@@ -1152,8 +1151,8 @@ pub struct IdRange {
 impl IdRange {
     pub fn max() -> IdRange {
         IdRange {
-            min: NodeId::from_u32(u32::MAX),
-            max: NodeId::from_u32(u32::MIN),
+            min: NodeId::MAX,
+            max: NodeId::from_u32(0),
         }
     }
 
diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs
index 896a6163eba64..501c17867f039 100644
--- a/src/librustc/hir/map/hir_id_validator.rs
+++ b/src/librustc/hir/map/hir_id_validator.rs
@@ -124,7 +124,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
                                        .enumerate()
                                        .find(|&(_, &entry)| hir_id == entry)
                                        .expect("no node_to_hir_id entry");
-                let node_id = NodeId::new(node_id);
+                let node_id = NodeId::from_usize(node_id);
                 missing_items.push(format!("[local_id: {}, node:{}]",
                                            local_id,
                                            self.hir_map.node_to_string(node_id)));
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 8cfbd27fc6163..8582900b72c83 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -393,7 +393,7 @@ impl Session {
 
         match id.as_usize().checked_add(count) {
             Some(next) => {
-                self.next_node_id.set(ast::NodeId::new(next));
+                self.next_node_id.set(ast::NodeId::from_usize(next));
             }
             None => bug!("Input too large, ran out of node ids!"),
         }
@@ -1160,7 +1160,7 @@ pub fn build_session_(
         recursion_limit: Once::new(),
         type_length_limit: Once::new(),
         const_eval_stack_frame_limit: 100,
-        next_node_id: OneThread::new(Cell::new(NodeId::new(1))),
+        next_node_id: OneThread::new(Cell::new(NodeId::from_u32(1))),
         allocator_kind: Once::new(),
         injected_panic_runtime: Once::new(),
         imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index b4f6d10b1f829..b26d4fd09e90b 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -566,7 +566,7 @@ impl FromStr for UserIdentifiedItem {
     type Err = ();
     fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
         Ok(s.parse()
-            .map(ast::NodeId::new)
+            .map(ast::NodeId::from_u32)
             .map(ItemViaNode)
             .unwrap_or_else(|_| ItemViaPath(s.split("::").map(|s| s.to_string()).collect())))
     }
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index a3694cd73ad53..5a91b50f6bcc9 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -663,7 +663,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         let mut errors = false;
         let mut seen_spans = FxHashSet::default();
         let mut error_vec = Vec::new();
-        let mut prev_root_id: NodeId = NodeId::new(0);
+        let mut prev_root_id: NodeId = NodeId::from_u32(0);
         for i in 0 .. self.determined_imports.len() {
             let import = self.determined_imports[i];
             let error = self.finalize_import(import);
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 2f17bc0548cad..b5ef14689f93a 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -18,7 +18,6 @@ pub use util::parser::ExprPrecedence;
 use ext::hygiene::{Mark, SyntaxContext};
 use print::pprust;
 use ptr::P;
-use rustc_data_structures::indexed_vec;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_target::spec::abi::Abi;
 use source_map::{dummy_spanned, respan, Spanned};
@@ -31,7 +30,6 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lrc;
 use serialize::{self, Decoder, Encoder};
 use std::fmt;
-use std::u32;
 
 pub use rustc_target::abi::FloatTy;
 
@@ -213,71 +211,53 @@ pub struct ParenthesisedArgs {
     pub output: Option<P<Ty>>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-pub struct NodeId(u32);
-
-impl NodeId {
-    pub fn new(x: usize) -> NodeId {
-        assert!(x < (u32::MAX as usize));
-        NodeId(x as u32)
-    }
-
-    pub fn from_u32(x: u32) -> NodeId {
-        NodeId(x)
-    }
-
-    pub fn as_usize(&self) -> usize {
-        self.0 as usize
+// hack to ensure that we don't try to access the private parts of `NodeId` in this module
+mod node_id_inner {
+    use rustc_data_structures::indexed_vec::Idx;
+    newtype_index! {
+        pub struct NodeId {
+            ENCODABLE = custom
+        }
     }
+}
 
-    pub fn as_u32(&self) -> u32 {
-        self.0
-    }
+pub use self::node_id_inner::NodeId;
 
+impl NodeId {
     pub fn placeholder_from_mark(mark: Mark) -> Self {
-        NodeId(mark.as_u32())
+        NodeId::from_u32(mark.as_u32())
     }
 
     pub fn placeholder_to_mark(self) -> Mark {
-        Mark::from_u32(self.0)
+        Mark::from_u32(self.as_u32())
     }
 }
 
 impl fmt::Display for NodeId {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&self.0, f)
+        fmt::Display::fmt(&self.as_u32(), f)
     }
 }
 
 impl serialize::UseSpecializedEncodable for NodeId {
     fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_u32(self.0)
+        s.emit_u32(self.as_u32())
     }
 }
 
 impl serialize::UseSpecializedDecodable for NodeId {
     fn default_decode<D: Decoder>(d: &mut D) -> Result<NodeId, D::Error> {
-        d.read_u32().map(NodeId)
-    }
-}
-
-impl indexed_vec::Idx for NodeId {
-    fn new(idx: usize) -> Self {
-        NodeId::new(idx)
-    }
-
-    fn index(self) -> usize {
-        self.as_usize()
+        d.read_u32().map(NodeId::from_u32)
     }
 }
 
 /// Node id used to represent the root of the crate.
-pub const CRATE_NODE_ID: NodeId = NodeId(0);
+pub const CRATE_NODE_ID: NodeId = NodeId::from_u32_const(0);
 
 /// When parsing and doing expansions, we initially give all AST nodes this AST
 /// node value. Then later, in the renumber pass, we renumber them to have
 /// small, positive ids.
-pub const DUMMY_NODE_ID: NodeId = NodeId(!0);
+pub const DUMMY_NODE_ID: NodeId = NodeId::MAX;
 
 /// A modifier on a bound, currently this is only used for `?Sized`, where the
 /// modifier is `Maybe`. Negative bounds should also be handled here.
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index e9a6535cba1d2..9bbd59e09be15 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -26,6 +26,7 @@
 #![feature(rustc_diagnostic_macros)]
 #![feature(slice_sort_by_cached_key)]
 #![feature(str_escape)]
+#![feature(step_trait)]
 #![feature(try_trait)]
 #![feature(unicode_internals)]
 
@@ -37,7 +38,7 @@ extern crate serialize;
 #[macro_use] extern crate log;
 pub extern crate rustc_errors as errors;
 extern crate syntax_pos;
-extern crate rustc_data_structures;
+#[macro_use] extern crate rustc_data_structures;
 extern crate rustc_target;
 #[macro_use] extern crate scoped_tls;
 #[macro_use]

From a1d89266e5f96a2232c7202bf812dee1f845ae02 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Wed, 7 Nov 2018 11:01:18 +0100
Subject: [PATCH 2/7] Turn `HirLocalId` into a `newtype_index`

---
 src/librustc/dep_graph/dep_node.rs       |  6 ++--
 src/librustc/hir/lowering.rs             |  4 +--
 src/librustc/hir/map/hir_id_validator.rs |  4 +--
 src/librustc/hir/mod.rs                  | 45 +++++++++---------------
 src/librustc/ich/impls_hir.rs            | 11 ++++--
 src/librustc_driver/pretty.rs            |  8 ++---
 6 files changed, 36 insertions(+), 42 deletions(-)

diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 61996b5a8a75c..3ff2545f78dfa 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -63,7 +63,7 @@
 use mir::interpret::GlobalId;
 use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
 use hir::map::DefPathHash;
-use hir::{HirId, ItemLocalId};
+use hir::HirId;
 
 use ich::{Fingerprint, StableHashingContext};
 use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
@@ -790,11 +790,11 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for HirId {
     fn to_fingerprint(&self, tcx: TyCtxt<'_, '_, '_>) -> Fingerprint {
         let HirId {
             owner,
-            local_id: ItemLocalId(local_id),
+            local_id,
         } = *self;
 
         let def_path_hash = tcx.def_path_hash(DefId::local(owner));
-        let local_id = Fingerprint::from_smaller_hash(local_id as u64);
+        let local_id = Fingerprint::from_smaller_hash(local_id.as_u32().into());
 
         def_path_hash.0.combine(local_id)
     }
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index dd5d4b8f6afff..e532b50a28b6b 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -588,7 +588,7 @@ impl<'a> LoweringContext<'a> {
             *local_id_counter += 1;
             hir::HirId {
                 owner: def_index,
-                local_id: hir::ItemLocalId(local_id),
+                local_id: hir::ItemLocalId::from_u32(local_id),
             }
         })
     }
@@ -616,7 +616,7 @@ impl<'a> LoweringContext<'a> {
 
             hir::HirId {
                 owner: def_index,
-                local_id: hir::ItemLocalId(local_id),
+                local_id: hir::ItemLocalId::from_u32(local_id),
             }
         })
     }
diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs
index 501c17867f039..ac4119dc372d3 100644
--- a/src/librustc/hir/map/hir_id_validator.rs
+++ b/src/librustc/hir/map/hir_id_validator.rs
@@ -101,7 +101,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
         if max != self.hir_ids_seen.len() - 1 {
             // Collect the missing ItemLocalIds
             let missing: Vec<_> = (0 .. max as u32 + 1)
-              .filter(|&i| !self.hir_ids_seen.contains_key(&ItemLocalId(i)))
+              .filter(|&i| !self.hir_ids_seen.contains_key(&ItemLocalId::from_u32(i)))
               .collect();
 
             // Try to map those to something more useful
@@ -110,7 +110,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
             for local_id in missing {
                 let hir_id = HirId {
                     owner: owner_def_index,
-                    local_id: ItemLocalId(local_id as u32),
+                    local_id: ItemLocalId::from_u32(local_id),
                 };
 
                 trace!("missing hir id {:#?}", hir_id);
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index f57e3ff913b38..bfe1649380581 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -37,7 +37,6 @@ use syntax::util::parser::ExprPrecedence;
 use ty::AdtKind;
 use ty::query::Providers;
 
-use rustc_data_structures::indexed_vec;
 use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, scope};
 use rustc_data_structures::thin_vec::ThinVec;
 
@@ -121,40 +120,28 @@ impl serialize::UseSpecializedDecodable for HirId {
     }
 }
 
-
-/// An `ItemLocalId` uniquely identifies something within a given "item-like",
-/// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
-/// guarantee that the numerical value of a given `ItemLocalId` corresponds to
-/// the node's position within the owning item in any way, but there is a
-/// guarantee that the `LocalItemId`s within an owner occupy a dense range of
-/// integers starting at zero, so a mapping that maps all or most nodes within
-/// an "item-like" to something else can be implement by a `Vec` instead of a
-/// tree or hash map.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
-         RustcEncodable, RustcDecodable)]
-pub struct ItemLocalId(pub u32);
-
-impl ItemLocalId {
-    pub fn as_usize(&self) -> usize {
-        self.0 as usize
+// hack to ensure that we don't try to access the private parts of `NodeId` in this module
+mod item_local_id_inner {
+    use rustc_data_structures::indexed_vec::Idx;
+    /// An `ItemLocalId` uniquely identifies something within a given "item-like",
+    /// that is within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no
+    /// guarantee that the numerical value of a given `ItemLocalId` corresponds to
+    /// the node's position within the owning item in any way, but there is a
+    /// guarantee that the `LocalItemId`s within an owner occupy a dense range of
+    /// integers starting at zero, so a mapping that maps all or most nodes within
+    /// an "item-like" to something else can be implement by a `Vec` instead of a
+    /// tree or hash map.
+    newtype_index! {
+        pub struct ItemLocalId { .. }
     }
 }
 
-impl indexed_vec::Idx for ItemLocalId {
-    fn new(idx: usize) -> Self {
-        debug_assert!((idx as u32) as usize == idx);
-        ItemLocalId(idx as u32)
-    }
-
-    fn index(self) -> usize {
-        self.0 as usize
-    }
-}
+pub use self::item_local_id_inner::ItemLocalId;
 
 /// The `HirId` corresponding to CRATE_NODE_ID and CRATE_DEF_INDEX
 pub const CRATE_HIR_ID: HirId = HirId {
     owner: CRATE_DEF_INDEX,
-    local_id: ItemLocalId(0)
+    local_id: ItemLocalId::from_u32_const(0)
 };
 
 pub const DUMMY_HIR_ID: HirId = HirId {
@@ -162,7 +149,7 @@ pub const DUMMY_HIR_ID: HirId = HirId {
     local_id: DUMMY_ITEM_LOCAL_ID,
 };
 
-pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId(!0);
+pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX;
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Copy)]
 pub struct Label {
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index b220634d0d903..ae0d78d2958ad 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -79,7 +79,14 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
     }
 }
 
-impl_stable_hash_for!(tuple_struct hir::ItemLocalId { index });
+impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemLocalId {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        self.as_u32().hash_stable(hcx, hasher);
+    }
+}
 
 impl<'a> ToStableHashKey<StableHashingContext<'a>>
 for hir::ItemLocalId {
@@ -800,7 +807,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
             .iter()
             .map(|id| {
                 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
-                debug_assert_eq!(local_id, hir::ItemLocalId(0));
+                debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0));
                 def_path_hash.0
             }).fold(Fingerprint::ZERO, |a, b| {
                 a.combine_commutative(b)
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index b26d4fd09e90b..c7ba31e339570 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -425,7 +425,7 @@ impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> {
             pprust_hir::AnnNode::Item(item) => {
                 s.s.space()?;
                 s.synth_comment(format!("node_id: {} hir local_id: {}",
-                                        item.id, item.hir_id.local_id.0))
+                                        item.id, item.hir_id.local_id.as_u32()))
             }
             pprust_hir::AnnNode::SubItem(id) => {
                 s.s.space()?;
@@ -434,18 +434,18 @@ impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> {
             pprust_hir::AnnNode::Block(blk) => {
                 s.s.space()?;
                 s.synth_comment(format!("block node_id: {} hir local_id: {}",
-                                        blk.id, blk.hir_id.local_id.0))
+                                        blk.id, blk.hir_id.local_id.as_u32()))
             }
             pprust_hir::AnnNode::Expr(expr) => {
                 s.s.space()?;
                 s.synth_comment(format!("node_id: {} hir local_id: {}",
-                                        expr.id, expr.hir_id.local_id.0))?;
+                                        expr.id, expr.hir_id.local_id.as_u32()))?;
                 s.pclose()
             }
             pprust_hir::AnnNode::Pat(pat) => {
                 s.s.space()?;
                 s.synth_comment(format!("pat node_id: {} hir local_id: {}",
-                                        pat.id, pat.hir_id.local_id.0))
+                                        pat.id, pat.hir_id.local_id.as_u32()))
             }
         }
     }

From 4bf7c33b79405f4cd6c2b6dd05a2bc270e3658a2 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Thu, 8 Nov 2018 10:44:40 +0100
Subject: [PATCH 3/7] Fix rustdoc

---
 src/librustdoc/passes/collect_intra_doc_links.rs | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index a780322e85e86..471ba6345e248 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -243,7 +243,7 @@ fn look_for_tests<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx>(
         if tests.found_tests == 0 {
             let mut diag = cx.tcx.struct_span_lint_node(
                 lint::builtin::MISSING_DOC_CODE_EXAMPLES,
-                NodeId::new(0),
+                NodeId::from_u32(0),
                 span_of_attrs(&item.attrs),
                 "Missing code example in this documentation");
             diag.emit();
@@ -281,14 +281,14 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor
         let current_item = match item.inner {
             ModuleItem(..) => {
                 if item.attrs.inner_docs {
-                    if item_node_id.unwrap() != NodeId::new(0) {
+                    if item_node_id.unwrap() != NodeId::from_u32(0) {
                         item.name.clone()
                     } else {
                         None
                     }
                 } else {
                     match parent_node.or(self.mod_ids.last().cloned()) {
-                        Some(parent) if parent != NodeId::new(0) => {
+                        Some(parent) if parent != NodeId::from_u32(0) => {
                             //FIXME: can we pull the parent module's name from elsewhere?
                             Some(self.cx.tcx.hir.name(parent).to_string())
                         }
@@ -538,13 +538,13 @@ fn resolution_failure(
             );
 
             diag = cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
-                                                NodeId::new(0),
+                                                NodeId::from_u32(0),
                                                 sp,
                                                 &msg);
             diag.span_label(sp, "cannot be resolved, ignoring");
         } else {
             diag = cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
-                                                NodeId::new(0),
+                                                NodeId::from_u32(0),
                                                 sp,
                                                 &msg);
 
@@ -564,7 +564,7 @@ fn resolution_failure(
         diag
     } else {
         cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
-                                     NodeId::new(0),
+                                     NodeId::from_u32(0),
                                      sp,
                                      &msg)
     };

From 4c9ee595841375ab94a8f1b18c524809addaf3fa Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Thu, 8 Nov 2018 15:00:55 +0100
Subject: [PATCH 4/7] Reintroduce the original debug formatting for NodeIds

---
 src/libsyntax/ast.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index b5ef14689f93a..4d56acabf1bba 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -217,6 +217,7 @@ mod node_id_inner {
     newtype_index! {
         pub struct NodeId {
             ENCODABLE = custom
+            DEBUG_FORMAT = "NodeId({})"
         }
     }
 }

From e5fd34c1aec57b60a96fa96568fe878209e052f3 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Thu, 8 Nov 2018 18:23:52 +0100
Subject: [PATCH 5/7] Fix fulldeps test with NodeId

---
 src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs b/src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs
index f2f14f84923c0..2c5de33232754 100644
--- a/src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs
@@ -43,7 +43,7 @@ fn expand_mbe_matches(cx: &mut ExtCtxt, _: Span, args: &[TokenTree])
                                     &[],
                                     Edition::Edition2015,
                                     // not used...
-                                    NodeId::new(0));
+                                    NodeId::from_u32(0));
     let map = match TokenTree::parse(cx, &mbe_matcher, args.iter().cloned().collect()) {
         Success(map) => map,
         Failure(_, tok) => {

From 3e5dfdd6f6bb8164a5924c65811bce353fbf4bf7 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Fri, 9 Nov 2018 11:00:39 +0100
Subject: [PATCH 6/7] Typo nit

---
 src/librustc/hir/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index bfe1649380581..a2b15f00265ab 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -120,7 +120,7 @@ impl serialize::UseSpecializedDecodable for HirId {
     }
 }
 
-// hack to ensure that we don't try to access the private parts of `NodeId` in this module
+// hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module
 mod item_local_id_inner {
     use rustc_data_structures::indexed_vec::Idx;
     /// An `ItemLocalId` uniquely identifies something within a given "item-like",

From 22039597e103a44b058755e2cc60736cf1fa5392 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Fri, 9 Nov 2018 11:00:51 +0100
Subject: [PATCH 7/7] Fix fallout it rustc_driver tests

---
 src/librustc_driver/test.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 28b7c610a91c0..8865c7e438e5e 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -232,20 +232,20 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
         // children of 1, etc
 
         let dscope = region::Scope {
-            id: hir::ItemLocalId(1),
+            id: hir::ItemLocalId::from_u32(1),
             data: region::ScopeData::Destruction,
         };
         self.region_scope_tree.record_scope_parent(dscope, None);
         self.create_region_hierarchy(
             &RH {
-                id: hir::ItemLocalId(1),
+                id: hir::ItemLocalId::from_u32(1),
                 sub: &[
                     RH {
-                        id: hir::ItemLocalId(10),
+                        id: hir::ItemLocalId::from_u32(10),
                         sub: &[],
                     },
                     RH {
-                        id: hir::ItemLocalId(11),
+                        id: hir::ItemLocalId::from_u32(11),
                         sub: &[],
                     },
                 ],
@@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
 
     pub fn t_rptr_scope(&self, id: u32) -> Ty<'tcx> {
         let r = ty::ReScope(region::Scope {
-            id: hir::ItemLocalId(id),
+            id: hir::ItemLocalId::from_u32(id),
             data: region::ScopeData::Node,
         });
         self.infcx