diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 6f1287014d7..3026e047626 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -32,11 +32,10 @@ use middle::typeck::infer;
 use middle::{typeck, ty, def, pat_util, stability};
 use middle::const_eval::{eval_const_expr_partial, const_int, const_uint};
 use util::ppaux::{ty_to_string};
-use util::nodemap::NodeSet;
+use util::nodemap::{FnvHashMap, NodeSet};
 use lint::{Context, LintPass, LintArray};
 
 use std::cmp;
-use std::collections::HashMap;
 use std::collections::hash_map::{Occupied, Vacant};
 use std::slice;
 use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
@@ -1284,7 +1283,7 @@ impl UnusedMut {
         // collect all mutable pattern and group their NodeIDs by their Identifier to
         // avoid false warnings in match arms with multiple patterns
 
-        let mut mutables = HashMap::new();
+        let mut mutables = FnvHashMap::new();
         for p in pats.iter() {
             pat_util::pat_bindings(&cx.tcx.def_map, &**p, |mode, id, _, path1| {
                 let ident = path1.node;
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 76187f192c2..7f8b779dac1 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -34,8 +34,8 @@ use driver::early_error;
 use lint::{Level, LevelSource, Lint, LintId, LintArray, LintPass, LintPassObject};
 use lint::{Default, CommandLine, Node, Allow, Warn, Deny, Forbid};
 use lint::builtin;
+use util::nodemap::FnvHashMap;
 
-use std::collections::HashMap;
 use std::rc::Rc;
 use std::cell::RefCell;
 use std::tuple::Tuple2;
@@ -63,14 +63,14 @@ pub struct LintStore {
     passes: Option<Vec<LintPassObject>>,
 
     /// Lints indexed by name.
-    by_name: HashMap<String, TargetLint>,
+    by_name: FnvHashMap<String, TargetLint>,
 
     /// Current levels of each lint, and where they were set.
-    levels: HashMap<LintId, LevelSource>,
+    levels: FnvHashMap<LintId, LevelSource>,
 
     /// Map of registered lint groups to what lints they expand to. The bool
     /// is true if the lint group was added by a plugin.
-    lint_groups: HashMap<&'static str, (Vec<LintId>, bool)>,
+    lint_groups: FnvHashMap<&'static str, (Vec<LintId>, bool)>,
 }
 
 /// The targed of the `by_name` map, which accounts for renaming/deprecation.
@@ -102,9 +102,9 @@ impl LintStore {
         LintStore {
             lints: vec!(),
             passes: Some(vec!()),
-            by_name: HashMap::new(),
-            levels: HashMap::new(),
-            lint_groups: HashMap::new(),
+            by_name: FnvHashMap::new(),
+            levels: FnvHashMap::new(),
+            lint_groups: FnvHashMap::new(),
         }
     }
 
@@ -279,7 +279,8 @@ impl LintStore {
                 Some(lint_id) => self.set_level(lint_id, (level, CommandLine)),
                 None => {
                     match self.lint_groups.iter().map(|(&x, pair)| (x, pair.ref0().clone()))
-                                                 .collect::<HashMap<&'static str, Vec<LintId>>>()
+                                                 .collect::<FnvHashMap<&'static str,
+                                                                       Vec<LintId>>>()
                                                  .find_equiv(lint_name.as_slice()) {
                         Some(v) => {
                             v.iter()
@@ -317,7 +318,7 @@ pub struct Context<'a, 'tcx: 'a> {
 
     /// Level of lints for certain NodeIds, stored here because the body of
     /// the lint needs to run in trans.
-    node_levels: RefCell<HashMap<(ast::NodeId, LintId), LevelSource>>,
+    node_levels: RefCell<FnvHashMap<(ast::NodeId, LintId), LevelSource>>,
 }
 
 /// Convenience macro for calling a `LintPass` method on every pass in the context.
@@ -425,7 +426,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
             exported_items: exported_items,
             lints: lint_store,
             level_stack: vec![],
-            node_levels: RefCell::new(HashMap::new()),
+            node_levels: RefCell::new(FnvHashMap::new()),
         }
     }
 
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 91d7eeaf8f2..dbf0e405408 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -21,9 +21,9 @@ use metadata::decoder;
 use metadata::loader;
 use metadata::loader::CratePaths;
 use plugin::load::PluginMetadata;
+use util::nodemap::FnvHashMap;
 
 use std::rc::Rc;
-use std::collections::HashMap;
 use std::collections::hash_map::{Occupied, Vacant};
 use syntax::ast;
 use syntax::abi;
@@ -85,7 +85,7 @@ fn dump_crates(cstore: &CStore) {
 }
 
 fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
-    let mut map = HashMap::new();
+    let mut map = FnvHashMap::new();
     cstore.iter_crate_data(|cnum, data| {
         match map.entry(data.name()) {
             Vacant(entry) => { entry.set(vec![cnum]); },
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index 36456b3c4a9..f2c84bdabfc 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -16,11 +16,11 @@
 use back::svh::Svh;
 use metadata::decoder;
 use metadata::loader;
+use util::nodemap::{FnvHashMap, NodeMap};
 
 use std::cell::RefCell;
 use std::c_vec::CVec;
 use std::rc::Rc;
-use std::collections::HashMap;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token::IdentInterner;
@@ -29,7 +29,7 @@ use syntax::parse::token::IdentInterner;
 // local crate numbers (as generated during this session). Each external
 // crate may refer to types in other external crates, and each has their
 // own crate numbers.
-pub type cnum_map = HashMap<ast::CrateNum, ast::CrateNum>;
+pub type cnum_map = FnvHashMap<ast::CrateNum, ast::CrateNum>;
 
 pub enum MetadataBlob {
     MetadataVec(CVec<u8>),
@@ -67,22 +67,20 @@ pub struct CrateSource {
 }
 
 pub struct CStore {
-    metas: RefCell<HashMap<ast::CrateNum, Rc<crate_metadata>>>,
-    extern_mod_crate_map: RefCell<extern_mod_crate_map>,
+    metas: RefCell<FnvHashMap<ast::CrateNum, Rc<crate_metadata>>>,
+    /// Map from NodeId's of local extern crate statements to crate numbers
+    extern_mod_crate_map: RefCell<NodeMap<ast::CrateNum>>,
     used_crate_sources: RefCell<Vec<CrateSource>>,
     used_libraries: RefCell<Vec<(String, NativeLibaryKind)>>,
     used_link_args: RefCell<Vec<String>>,
     pub intr: Rc<IdentInterner>,
 }
 
-// Map from NodeId's of local extern crate statements to crate numbers
-type extern_mod_crate_map = HashMap<ast::NodeId, ast::CrateNum>;
-
 impl CStore {
     pub fn new(intr: Rc<IdentInterner>) -> CStore {
         CStore {
-            metas: RefCell::new(HashMap::new()),
-            extern_mod_crate_map: RefCell::new(HashMap::new()),
+            metas: RefCell::new(FnvHashMap::new()),
+            extern_mod_crate_map: RefCell::new(FnvHashMap::new()),
             used_crate_sources: RefCell::new(Vec::new()),
             used_libraries: RefCell::new(Vec::new()),
             used_link_args: RefCell::new(Vec::new()),
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 66b647fabdc..251b7c0c141 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -23,13 +23,12 @@ use middle::ty::{lookup_item_type};
 use middle::ty;
 use middle::stability;
 use middle;
-use util::nodemap::{NodeMap, NodeSet};
+use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
 
 use serialize::Encodable;
 use std::cell::RefCell;
 use std::hash::Hash;
 use std::hash;
-use std::collections::HashMap;
 use syntax::abi;
 use syntax::ast::*;
 use syntax::ast;
@@ -2062,7 +2061,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, parms: EncodeParams, krate:
         link_meta: link_meta,
         cstore: cstore,
         encode_inlined_item: RefCell::new(encode_inlined_item),
-        type_abbrevs: RefCell::new(HashMap::new()),
+        type_abbrevs: RefCell::new(FnvHashMap::new()),
         reachable: reachable,
      };
 
@@ -2167,7 +2166,7 @@ pub fn encoded_ty(tcx: &ty::ctxt, t: ty::t) -> String {
         diag: tcx.sess.diagnostic(),
         ds: def_to_string,
         tcx: tcx,
-        abbrevs: &RefCell::new(HashMap::new())
+        abbrevs: &RefCell::new(FnvHashMap::new())
     }, t);
     String::from_utf8(wr.unwrap()).unwrap()
 }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index a7b64cb20e5..56e44b69a5f 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -14,12 +14,12 @@
 #![allow(non_camel_case_types)]
 
 use std::cell::RefCell;
-use std::collections::HashMap;
 
 use middle::subst;
 use middle::subst::VecPerParamSpace;
 use middle::ty::ParamTy;
 use middle::ty;
+use util::nodemap::FnvHashMap;
 
 use syntax::abi::Abi;
 use syntax::ast;
@@ -47,7 +47,7 @@ pub struct ty_abbrev {
     s: String
 }
 
-pub type abbrev_map = RefCell<HashMap<ty::t, ty_abbrev>>;
+pub type abbrev_map = RefCell<FnvHashMap<ty::t, ty_abbrev>>;
 
 pub fn enc_ty(w: &mut SeekableMemWriter, cx: &ctxt, t: ty::t) {
     match cx.abbrevs.borrow_mut().get(&t) {
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index aaf3b16c5ee..0ca53054f1c 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -1161,7 +1161,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         })
     }
 
-    for &ty in tcx.node_types.borrow().get(&(id as uint)).iter() {
+    for &ty in tcx.node_types.borrow().get(&id).iter() {
         rbml_w.tag(c::tag_table_node_type, |rbml_w| {
             rbml_w.id(id);
             rbml_w.tag(c::tag_table_val, |rbml_w| {
@@ -1825,7 +1825,7 @@ fn decode_side_tables(dcx: &DecodeContext,
                         let ty = val_dsr.read_ty(dcx);
                         debug!("inserting ty for node {}: {}",
                                id, ty_to_string(dcx.tcx, ty));
-                        dcx.tcx.node_types.borrow_mut().insert(id as uint, ty);
+                        dcx.tcx.node_types.borrow_mut().insert(id, ty);
                     }
                     c::tag_table_item_subst => {
                         let item_substs = ty::ItemSubsts {
diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs
index 2a92db3e7d4..becc0dbf624 100644
--- a/src/librustc/middle/borrowck/move_data.rs
+++ b/src/librustc/middle/borrowck/move_data.rs
@@ -18,7 +18,6 @@ comments in the section "Moves and initialization" and in `doc.rs`.
 use std::cell::RefCell;
 use std::rc::Rc;
 use std::uint;
-use std::collections::{HashMap, HashSet};
 use middle::borrowck::*;
 use middle::cfg;
 use middle::dataflow::DataFlowContext;
@@ -30,6 +29,7 @@ use middle::ty;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::Span;
+use util::nodemap::{FnvHashMap, NodeSet};
 use util::ppaux::Repr;
 
 pub struct MoveData {
@@ -37,7 +37,7 @@ pub struct MoveData {
     pub paths: RefCell<Vec<MovePath>>,
 
     /// Cache of loan path to move path index, for easy lookup.
-    pub path_map: RefCell<HashMap<Rc<LoanPath>, MovePathIndex>>,
+    pub path_map: RefCell<FnvHashMap<Rc<LoanPath>, MovePathIndex>>,
 
     /// Each move or uninitialized variable gets an entry here.
     pub moves: RefCell<Vec<Move>>,
@@ -53,7 +53,7 @@ pub struct MoveData {
     pub path_assignments: RefCell<Vec<Assignment>>,
 
     /// Assignments to a variable or path, like `x = foo`, but not `x += foo`.
-    pub assignee_ids: RefCell<HashSet<ast::NodeId>>,
+    pub assignee_ids: RefCell<NodeSet>,
 }
 
 pub struct FlowedMoveData<'a, 'tcx: 'a> {
@@ -183,11 +183,11 @@ impl MoveData {
     pub fn new() -> MoveData {
         MoveData {
             paths: RefCell::new(Vec::new()),
-            path_map: RefCell::new(HashMap::new()),
+            path_map: RefCell::new(FnvHashMap::new()),
             moves: RefCell::new(Vec::new()),
             path_assignments: RefCell::new(Vec::new()),
             var_assignments: RefCell::new(Vec::new()),
-            assignee_ids: RefCell::new(HashSet::new()),
+            assignee_ids: RefCell::new(NodeSet::new()),
         }
     }
 
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index bfabcc958d7..75e61690685 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -61,7 +61,6 @@
 //! Additionally, the algorithm is geared towards finding *any* solution rather
 //! than finding a number of solutions (there are normally quite a few).
 
-use std::collections::HashMap;
 use syntax::ast;
 
 use driver::session;
@@ -69,6 +68,7 @@ use driver::config;
 use metadata::cstore;
 use metadata::csearch;
 use middle::ty;
+use util::nodemap::FnvHashMap;
 
 /// A list of dependencies for a certain crate type.
 ///
@@ -81,7 +81,7 @@ pub type DependencyList = Vec<Option<cstore::LinkagePreference>>;
 /// A mapping of all required dependencies for a particular flavor of output.
 ///
 /// This is local to the tcx, and is generally relevant to one session.
-pub type Dependencies = HashMap<config::CrateType, DependencyList>;
+pub type Dependencies = FnvHashMap<config::CrateType, DependencyList>;
 
 pub fn calculate(tcx: &ty::ctxt) {
     let mut fmts = tcx.dependency_formats.borrow_mut();
@@ -137,7 +137,7 @@ fn calculate_type(sess: &session::Session,
         config::CrateTypeExecutable | config::CrateTypeDylib => {},
     }
 
-    let mut formats = HashMap::new();
+    let mut formats = FnvHashMap::new();
 
     // Sweep all crates for found dylibs. Add all dylibs, as well as their
     // dependencies, ensuring there are no conflicts. The only valid case for a
@@ -208,7 +208,7 @@ fn calculate_type(sess: &session::Session,
 fn add_library(sess: &session::Session,
                cnum: ast::CrateNum,
                link: cstore::LinkagePreference,
-               m: &mut HashMap<ast::CrateNum, cstore::LinkagePreference>) {
+               m: &mut FnvHashMap<ast::CrateNum, cstore::LinkagePreference>) {
     match m.get(&cnum) {
         Some(&link2) => {
             // If the linkages differ, then we'd have two copies of the library
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 1f3473c159f..c575d2fc4bf 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -24,6 +24,8 @@ use driver::session::Session;
 use metadata::csearch::each_lang_item;
 use middle::ty;
 use middle::weak_lang_items;
+use util::nodemap::FnvHashMap;
+
 use syntax::ast;
 use syntax::ast_util::local_def;
 use syntax::attr::AttrMetaMethods;
@@ -32,7 +34,6 @@ use syntax::parse::token::InternedString;
 use syntax::visit::Visitor;
 use syntax::visit;
 
-use std::collections::HashMap;
 use std::iter::Enumerate;
 use std::slice;
 
@@ -123,7 +124,7 @@ struct LanguageItemCollector<'a> {
 
     session: &'a Session,
 
-    item_refs: HashMap<&'static str, uint>,
+    item_refs: FnvHashMap<&'static str, uint>,
 }
 
 impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
@@ -148,7 +149,7 @@ impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
 
 impl<'a> LanguageItemCollector<'a> {
     pub fn new(session: &'a Session) -> LanguageItemCollector<'a> {
-        let mut item_refs = HashMap::new();
+        let mut item_refs = FnvHashMap::new();
 
         $( item_refs.insert($name, $variant as uint); )*
 
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index e320f47075e..bf524c85ed5 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -11,18 +11,18 @@
 use middle::def::*;
 use middle::resolve;
 use middle::ty;
+use util::nodemap::FnvHashMap;
 
-use std::collections::HashMap;
 use syntax::ast::*;
 use syntax::ast_util::{walk_pat};
 use syntax::codemap::{Span, DUMMY_SP};
 
-pub type PatIdMap = HashMap<Ident, NodeId>;
+pub type PatIdMap = FnvHashMap<Ident, NodeId>;
 
 // This is used because same-named variables in alternative patterns need to
 // use the NodeId of their namesake in the first pattern.
 pub fn pat_id_map(dm: &resolve::DefMap, pat: &Pat) -> PatIdMap {
-    let mut map = HashMap::new();
+    let mut map = FnvHashMap::new();
     pat_bindings(dm, pat, |_bm, p_id, _s, path1| {
         map.insert(path1.node, p_id);
     });
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index d380c35580d..2cc8f20b562 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -24,11 +24,10 @@ Most of the documentation on regions can be found in
 use driver::session::Session;
 use middle::ty::{FreeRegion};
 use middle::ty;
-use util::nodemap::NodeMap;
+use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
 use util::common::can_reach;
 
 use std::cell::RefCell;
-use std::collections::{HashMap, HashSet};
 use syntax::codemap::Span;
 use syntax::{ast, visit};
 use syntax::ast::{Block, Item, FnDecl, NodeId, Arm, Pat, Stmt, Expr, Local};
@@ -79,9 +78,9 @@ The region maps encode information about region relationships.
 pub struct RegionMaps {
     scope_map: RefCell<NodeMap<ast::NodeId>>,
     var_map: RefCell<NodeMap<ast::NodeId>>,
-    free_region_map: RefCell<HashMap<FreeRegion, Vec<FreeRegion>>>,
+    free_region_map: RefCell<FnvHashMap<FreeRegion, Vec<FreeRegion>>>,
     rvalue_scopes: RefCell<NodeMap<ast::NodeId>>,
-    terminating_scopes: RefCell<HashSet<ast::NodeId>>,
+    terminating_scopes: RefCell<NodeSet>,
 }
 
 pub struct Context {
@@ -876,9 +875,9 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
     let maps = RegionMaps {
         scope_map: RefCell::new(NodeMap::new()),
         var_map: RefCell::new(NodeMap::new()),
-        free_region_map: RefCell::new(HashMap::new()),
+        free_region_map: RefCell::new(FnvHashMap::new()),
         rvalue_scopes: RefCell::new(NodeMap::new()),
-        terminating_scopes: RefCell::new(HashSet::new()),
+        terminating_scopes: RefCell::new(NodeSet::new()),
     };
     {
         let mut visitor = RegionResolutionVisitor {
@@ -901,4 +900,3 @@ pub fn resolve_inlined_item(sess: &Session,
     };
     visit::walk_inlined_item(&mut visitor, item);
 }
-
diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs
index a2b80686d01..59fbcde85e8 100644
--- a/src/librustc/middle/save/mod.rs
+++ b/src/librustc/middle/save/mod.rs
@@ -261,7 +261,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             let span_utils = self.span;
             for &(id, ref p, _, _) in self.collected_paths.iter() {
                 let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
-                    (*self.analysis.ty_cx.node_types.borrow())[id as uint]);
+                    (*self.analysis.ty_cx.node_types.borrow())[id]);
                 // get the span only for the name of the variable (I hope the path is only ever a
                 // variable name, but who knows?)
                 self.fmt.formal_str(p.span,
@@ -427,7 +427,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                 let name = get_ident(ident);
                 let qualname = format!("{}::{}", qualname, name);
                 let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
-                    (*self.analysis.ty_cx.node_types.borrow())[field.node.id as uint]);
+                    (*self.analysis.ty_cx.node_types.borrow())[field.node.id]);
                 match self.span.sub_span_before_token(field.span, token::Colon) {
                     Some(sub_span) => self.fmt.field_str(field.span,
                                                          Some(sub_span),
@@ -1447,7 +1447,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
         for &(id, ref p, ref immut, _) in self.collected_paths.iter() {
             let value = if *immut { value.to_string() } else { "<mutable>".to_string() };
             let types = self.analysis.ty_cx.node_types.borrow();
-            let typ = ppaux::ty_to_string(&self.analysis.ty_cx, (*types)[id as uint]);
+            let typ = ppaux::ty_to_string(&self.analysis.ty_cx, (*types)[id]);
             // Get the span only for the name of the variable (I hope the path
             // is only ever a variable name, but who knows?).
             let sub_span = self.span.span_for_last_ident(p.span);
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index e148261b1bf..7b0ebe631e0 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -214,10 +214,10 @@ use middle::trans::type_of;
 use middle::trans::debuginfo;
 use middle::ty;
 use util::common::indenter;
+use util::nodemap::FnvHashMap;
 use util::ppaux::{Repr, vec_map_to_string};
 
 use std;
-use std::collections::HashMap;
 use std::iter::AdditiveIterator;
 use std::rc::Rc;
 use syntax::ast;
@@ -336,7 +336,7 @@ pub struct BindingInfo {
     pub ty: ty::t,
 }
 
-type BindingsMap = HashMap<Ident, BindingInfo>;
+type BindingsMap = FnvHashMap<Ident, BindingInfo>;
 
 struct ArmData<'p, 'blk, 'tcx: 'blk> {
     bodycx: Block<'blk, 'tcx>,
@@ -1291,7 +1291,7 @@ fn create_bindings_map(bcx: Block, pat: &ast::Pat,
     let ccx = bcx.ccx();
     let tcx = bcx.tcx();
     let reassigned = is_discr_reassigned(bcx, discr, body);
-    let mut bindings_map = HashMap::new();
+    let mut bindings_map = FnvHashMap::new();
     pat_bindings(&tcx.def_map, &*pat, |bm, p_id, span, path1| {
         let ident = path1.node;
         let variable_ty = node_id_type(bcx, p_id);
diff --git a/src/librustc/middle/trans/builder.rs b/src/librustc/middle/trans/builder.rs
index b692b01f765..3fd0a290153 100644
--- a/src/librustc/middle/trans/builder.rs
+++ b/src/librustc/middle/trans/builder.rs
@@ -18,7 +18,7 @@ use middle::trans::base;
 use middle::trans::common::*;
 use middle::trans::machine::llalign_of_pref;
 use middle::trans::type_::Type;
-use std::collections::HashMap;
+use util::nodemap::FnvHashMap;
 use libc::{c_uint, c_char};
 use std::string::String;
 use syntax::codemap::Span;
@@ -58,7 +58,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // Build version of path with cycles removed.
 
                 // Pass 1: scan table mapping str -> rightmost pos.
-                let mut mm = HashMap::new();
+                let mut mm = FnvHashMap::new();
                 let len = v.len();
                 let mut i = 0u;
                 while i < len {
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 18501dd9e34..c0380f87036 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -36,10 +36,9 @@ use middle::ty_fold::TypeFoldable;
 use middle::typeck;
 use middle::typeck::infer;
 use util::ppaux::Repr;
-use util::nodemap::{DefIdMap, NodeMap};
+use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
 
 use arena::TypedArena;
-use std::collections::HashMap;
 use libc::{c_uint, c_char};
 use std::c_str::ToCStr;
 use std::cell::{Cell, RefCell};
@@ -185,7 +184,7 @@ pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
     }
 }
 
-pub type ExternMap = HashMap<String, ValueRef>;
+pub type ExternMap = FnvHashMap<String, ValueRef>;
 
 // Here `self_ty` is the real type of the self parameter to this method. It
 // will only be set in the case of default methods.
diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs
index 7d2460093fe..b659da75222 100644
--- a/src/librustc/middle/trans/context.rs
+++ b/src/librustc/middle/trans/context.rs
@@ -27,13 +27,12 @@ use middle::trans::type_::{Type, TypeNames};
 use middle::ty;
 use util::ppaux::Repr;
 use util::sha2::Sha256;
-use util::nodemap::{NodeMap, NodeSet, DefIdMap};
+use util::nodemap::{NodeMap, NodeSet, DefIdMap, FnvHashMap, FnvHashSet};
 
 use std::cell::{Cell, RefCell};
 use std::c_str::ToCStr;
 use std::ptr;
 use std::rc::Rc;
-use std::collections::{HashMap, HashSet};
 use syntax::ast;
 use syntax::parse::token::InternedString;
 
@@ -47,7 +46,7 @@ pub struct Stats {
     pub n_inlines: Cell<uint>,
     pub n_closures: Cell<uint>,
     pub n_llvm_insns: Cell<uint>,
-    pub llvm_insns: RefCell<HashMap<String, uint>>,
+    pub llvm_insns: RefCell<FnvHashMap<String, uint>>,
     // (ident, time-in-ms, llvm-instructions)
     pub fn_stats: RefCell<Vec<(String, uint, uint)> >,
 }
@@ -70,8 +69,8 @@ pub struct SharedCrateContext<'tcx> {
     tcx: ty::ctxt<'tcx>,
     stats: Stats,
 
-    available_monomorphizations: RefCell<HashSet<String>>,
-    available_drop_glues: RefCell<HashMap<ty::t, String>>,
+    available_monomorphizations: RefCell<FnvHashSet<String>>,
+    available_drop_glues: RefCell<FnvHashMap<ty::t, String>>,
 }
 
 /// The local portion of a `CrateContext`.  There is one `LocalCrateContext`
@@ -85,8 +84,8 @@ pub struct LocalCrateContext {
     tn: TypeNames,
     externs: RefCell<ExternMap>,
     item_vals: RefCell<NodeMap<ValueRef>>,
-    drop_glues: RefCell<HashMap<ty::t, ValueRef>>,
-    tydescs: RefCell<HashMap<ty::t, Rc<tydesc_info>>>,
+    drop_glues: RefCell<FnvHashMap<ty::t, ValueRef>>,
+    tydescs: RefCell<FnvHashMap<ty::t, Rc<tydesc_info>>>,
     /// Set when running emit_tydescs to enforce that no more tydescs are
     /// created.
     finished_tydescs: Cell<bool>,
@@ -96,12 +95,12 @@ pub struct LocalCrateContext {
     /// came from)
     external_srcs: RefCell<NodeMap<ast::DefId>>,
     /// Cache instances of monomorphized functions
-    monomorphized: RefCell<HashMap<MonoId, ValueRef>>,
+    monomorphized: RefCell<FnvHashMap<MonoId, ValueRef>>,
     monomorphizing: RefCell<DefIdMap<uint>>,
     /// Cache generated vtables
-    vtables: RefCell<HashMap<(ty::t,Rc<ty::TraitRef>), ValueRef>>,
+    vtables: RefCell<FnvHashMap<(ty::t,Rc<ty::TraitRef>), ValueRef>>,
     /// Cache of constant strings,
-    const_cstr_cache: RefCell<HashMap<InternedString, ValueRef>>,
+    const_cstr_cache: RefCell<FnvHashMap<InternedString, ValueRef>>,
 
     /// Reverse-direction for const ptrs cast from globals.
     /// Key is an int, cast from a ValueRef holding a *T,
@@ -111,7 +110,7 @@ pub struct LocalCrateContext {
     /// when we ptrcast, and we have to ptrcast during translation
     /// of a [T] const because we form a slice, a [*T,int] pair, not
     /// a pointer to an LLVM array type.
-    const_globals: RefCell<HashMap<int, ValueRef>>,
+    const_globals: RefCell<FnvHashMap<int, ValueRef>>,
 
     /// Cache of emitted const values
     const_values: RefCell<NodeMap<ValueRef>>,
@@ -122,36 +121,36 @@ pub struct LocalCrateContext {
     /// Cache of external const values
     extern_const_values: RefCell<DefIdMap<ValueRef>>,
 
-    impl_method_cache: RefCell<HashMap<(ast::DefId, ast::Name), ast::DefId>>,
+    impl_method_cache: RefCell<FnvHashMap<(ast::DefId, ast::Name), ast::DefId>>,
 
     /// Cache of closure wrappers for bare fn's.
-    closure_bare_wrapper_cache: RefCell<HashMap<ValueRef, ValueRef>>,
+    closure_bare_wrapper_cache: RefCell<FnvHashMap<ValueRef, ValueRef>>,
 
-    lltypes: RefCell<HashMap<ty::t, Type>>,
-    llsizingtypes: RefCell<HashMap<ty::t, Type>>,
-    adt_reprs: RefCell<HashMap<ty::t, Rc<adt::Repr>>>,
-    type_hashcodes: RefCell<HashMap<ty::t, String>>,
-    all_llvm_symbols: RefCell<HashSet<String>>,
+    lltypes: RefCell<FnvHashMap<ty::t, Type>>,
+    llsizingtypes: RefCell<FnvHashMap<ty::t, Type>>,
+    adt_reprs: RefCell<FnvHashMap<ty::t, Rc<adt::Repr>>>,
+    type_hashcodes: RefCell<FnvHashMap<ty::t, String>>,
+    all_llvm_symbols: RefCell<FnvHashSet<String>>,
     int_type: Type,
     opaque_vec_type: Type,
     builder: BuilderRef_res,
 
     /// Holds the LLVM values for closure IDs.
-    unboxed_closure_vals: RefCell<HashMap<MonoId, ValueRef>>,
+    unboxed_closure_vals: RefCell<FnvHashMap<MonoId, ValueRef>>,
 
     dbg_cx: Option<debuginfo::CrateDebugContext>,
 
     eh_personality: RefCell<Option<ValueRef>>,
 
-    intrinsics: RefCell<HashMap<&'static str, ValueRef>>,
+    intrinsics: RefCell<FnvHashMap<&'static str, ValueRef>>,
 
     /// Number of LLVM instructions translated into this `LocalCrateContext`.
     /// This is used to perform some basic load-balancing to keep all LLVM
     /// contexts around the same size.
     n_llvm_insns: Cell<uint>,
 
-    trait_cache: RefCell<HashMap<Rc<ty::TraitRef>,
-                                 traits::Vtable<()>>>,
+    trait_cache: RefCell<FnvHashMap<Rc<ty::TraitRef>,
+                                    traits::Vtable<()>>>,
 }
 
 pub struct CrateContext<'a, 'tcx: 'a> {
@@ -269,11 +268,11 @@ impl<'tcx> SharedCrateContext<'tcx> {
                 n_inlines: Cell::new(0u),
                 n_closures: Cell::new(0u),
                 n_llvm_insns: Cell::new(0u),
-                llvm_insns: RefCell::new(HashMap::new()),
+                llvm_insns: RefCell::new(FnvHashMap::new()),
                 fn_stats: RefCell::new(Vec::new()),
             },
-            available_monomorphizations: RefCell::new(HashSet::new()),
-            available_drop_glues: RefCell::new(HashMap::new()),
+            available_monomorphizations: RefCell::new(FnvHashSet::new()),
+            available_drop_glues: RefCell::new(FnvHashMap::new()),
         };
 
         for i in range(0, local_count) {
@@ -393,37 +392,37 @@ impl LocalCrateContext {
                 llcx: llcx,
                 td: td,
                 tn: TypeNames::new(),
-                externs: RefCell::new(HashMap::new()),
+                externs: RefCell::new(FnvHashMap::new()),
                 item_vals: RefCell::new(NodeMap::new()),
-                drop_glues: RefCell::new(HashMap::new()),
-                tydescs: RefCell::new(HashMap::new()),
+                drop_glues: RefCell::new(FnvHashMap::new()),
+                tydescs: RefCell::new(FnvHashMap::new()),
                 finished_tydescs: Cell::new(false),
                 external: RefCell::new(DefIdMap::new()),
                 external_srcs: RefCell::new(NodeMap::new()),
-                monomorphized: RefCell::new(HashMap::new()),
+                monomorphized: RefCell::new(FnvHashMap::new()),
                 monomorphizing: RefCell::new(DefIdMap::new()),
-                vtables: RefCell::new(HashMap::new()),
-                const_cstr_cache: RefCell::new(HashMap::new()),
-                const_globals: RefCell::new(HashMap::new()),
+                vtables: RefCell::new(FnvHashMap::new()),
+                const_cstr_cache: RefCell::new(FnvHashMap::new()),
+                const_globals: RefCell::new(FnvHashMap::new()),
                 const_values: RefCell::new(NodeMap::new()),
                 static_values: RefCell::new(NodeMap::new()),
                 extern_const_values: RefCell::new(DefIdMap::new()),
-                impl_method_cache: RefCell::new(HashMap::new()),
-                closure_bare_wrapper_cache: RefCell::new(HashMap::new()),
-                lltypes: RefCell::new(HashMap::new()),
-                llsizingtypes: RefCell::new(HashMap::new()),
-                adt_reprs: RefCell::new(HashMap::new()),
-                type_hashcodes: RefCell::new(HashMap::new()),
-                all_llvm_symbols: RefCell::new(HashSet::new()),
+                impl_method_cache: RefCell::new(FnvHashMap::new()),
+                closure_bare_wrapper_cache: RefCell::new(FnvHashMap::new()),
+                lltypes: RefCell::new(FnvHashMap::new()),
+                llsizingtypes: RefCell::new(FnvHashMap::new()),
+                adt_reprs: RefCell::new(FnvHashMap::new()),
+                type_hashcodes: RefCell::new(FnvHashMap::new()),
+                all_llvm_symbols: RefCell::new(FnvHashSet::new()),
                 int_type: Type::from_ref(ptr::null_mut()),
                 opaque_vec_type: Type::from_ref(ptr::null_mut()),
                 builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)),
-                unboxed_closure_vals: RefCell::new(HashMap::new()),
+                unboxed_closure_vals: RefCell::new(FnvHashMap::new()),
                 dbg_cx: dbg_cx,
                 eh_personality: RefCell::new(None),
-                intrinsics: RefCell::new(HashMap::new()),
+                intrinsics: RefCell::new(FnvHashMap::new()),
                 n_llvm_insns: Cell::new(0u),
-                trait_cache: RefCell::new(HashMap::new()),
+                trait_cache: RefCell::new(FnvHashMap::new()),
             };
 
             local_ccx.int_type = Type::int(&local_ccx.dummy_ccx(shared));
@@ -575,11 +574,11 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.shared.link_meta
     }
 
-    pub fn drop_glues<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, ValueRef>> {
+    pub fn drop_glues<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::t, ValueRef>> {
         &self.local.drop_glues
     }
 
-    pub fn tydescs<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Rc<tydesc_info>>> {
+    pub fn tydescs<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::t, Rc<tydesc_info>>> {
         &self.local.tydescs
     }
 
@@ -595,7 +594,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.local.external_srcs
     }
 
-    pub fn monomorphized<'a>(&'a self) -> &'a RefCell<HashMap<MonoId, ValueRef>> {
+    pub fn monomorphized<'a>(&'a self) -> &'a RefCell<FnvHashMap<MonoId, ValueRef>> {
         &self.local.monomorphized
     }
 
@@ -603,15 +602,15 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.local.monomorphizing
     }
 
-    pub fn vtables<'a>(&'a self) -> &'a RefCell<HashMap<(ty::t,Rc<ty::TraitRef>), ValueRef>> {
+    pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<(ty::t,Rc<ty::TraitRef>), ValueRef>> {
         &self.local.vtables
     }
 
-    pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell<HashMap<InternedString, ValueRef>> {
+    pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell<FnvHashMap<InternedString, ValueRef>> {
         &self.local.const_cstr_cache
     }
 
-    pub fn const_globals<'a>(&'a self) -> &'a RefCell<HashMap<int, ValueRef>> {
+    pub fn const_globals<'a>(&'a self) -> &'a RefCell<FnvHashMap<int, ValueRef>> {
         &self.local.const_globals
     }
 
@@ -628,23 +627,23 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
     }
 
     pub fn impl_method_cache<'a>(&'a self)
-            -> &'a RefCell<HashMap<(ast::DefId, ast::Name), ast::DefId>> {
+            -> &'a RefCell<FnvHashMap<(ast::DefId, ast::Name), ast::DefId>> {
         &self.local.impl_method_cache
     }
 
-    pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell<HashMap<ValueRef, ValueRef>> {
+    pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell<FnvHashMap<ValueRef, ValueRef>> {
         &self.local.closure_bare_wrapper_cache
     }
 
-    pub fn lltypes<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Type>> {
+    pub fn lltypes<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::t, Type>> {
         &self.local.lltypes
     }
 
-    pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Type>> {
+    pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::t, Type>> {
         &self.local.llsizingtypes
     }
 
-    pub fn adt_reprs<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, Rc<adt::Repr>>> {
+    pub fn adt_reprs<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::t, Rc<adt::Repr>>> {
         &self.local.adt_reprs
     }
 
@@ -652,11 +651,11 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.shared.symbol_hasher
     }
 
-    pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, String>> {
+    pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::t, String>> {
         &self.local.type_hashcodes
     }
 
-    pub fn all_llvm_symbols<'a>(&'a self) -> &'a RefCell<HashSet<String>> {
+    pub fn all_llvm_symbols<'a>(&'a self) -> &'a RefCell<FnvHashSet<String>> {
         &self.local.all_llvm_symbols
     }
 
@@ -664,11 +663,11 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.shared.stats
     }
 
-    pub fn available_monomorphizations<'a>(&'a self) -> &'a RefCell<HashSet<String>> {
+    pub fn available_monomorphizations<'a>(&'a self) -> &'a RefCell<FnvHashSet<String>> {
         &self.shared.available_monomorphizations
     }
 
-    pub fn available_drop_glues<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, String>> {
+    pub fn available_drop_glues<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::t, String>> {
         &self.shared.available_drop_glues
     }
 
@@ -680,7 +679,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         self.local.opaque_vec_type
     }
 
-    pub fn unboxed_closure_vals<'a>(&'a self) -> &'a RefCell<HashMap<MonoId,ValueRef>> {
+    pub fn unboxed_closure_vals<'a>(&'a self) -> &'a RefCell<FnvHashMap<MonoId,ValueRef>> {
         &self.local.unboxed_closure_vals
     }
 
@@ -692,7 +691,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.local.eh_personality
     }
 
-    fn intrinsics<'a>(&'a self) -> &'a RefCell<HashMap<&'static str, ValueRef>> {
+    fn intrinsics<'a>(&'a self) -> &'a RefCell<FnvHashMap<&'static str, ValueRef>> {
         &self.local.intrinsics
     }
 
@@ -700,7 +699,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         self.local.n_llvm_insns.set(self.local.n_llvm_insns.get() + 1);
     }
 
-    pub fn trait_cache(&self) -> &RefCell<HashMap<Rc<ty::TraitRef>, traits::Vtable<()>>> {
+    pub fn trait_cache(&self) -> &RefCell<FnvHashMap<Rc<ty::TraitRef>, traits::Vtable<()>>> {
         &self.local.trait_cache
     }
 
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index 5b2e978e11f..fb6347af698 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -200,13 +200,12 @@ use middle::trans::type_::Type;
 use middle::trans;
 use middle::ty;
 use middle::pat_util;
+use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
 use util::ppaux;
 
 use libc::c_uint;
 use std::c_str::{CString, ToCStr};
 use std::cell::{Cell, RefCell};
-use std::collections::HashMap;
-use std::collections::HashSet;
 use std::ptr;
 use std::rc::{Rc, Weak};
 use syntax::util::interner::Interner;
@@ -258,11 +257,11 @@ struct TypeMap {
     // The UniqueTypeIds created so far
     unique_id_interner: Interner<Rc<String>>,
     // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
-    unique_id_to_metadata: HashMap<UniqueTypeId, DIType>,
-    // A map from ty::type_id() to debuginfo metadata. This is a N:1 mapping.
-    type_to_metadata: HashMap<uint, DIType>,
-    // A map from ty::type_id() to UniqueTypeId. This is a N:1 mapping.
-    type_to_unique_id: HashMap<uint, UniqueTypeId>
+    unique_id_to_metadata: FnvHashMap<UniqueTypeId, DIType>,
+    // A map from types to debuginfo metadata. This is a N:1 mapping.
+    type_to_metadata: FnvHashMap<ty::t, DIType>,
+    // A map from types to UniqueTypeId. This is a N:1 mapping.
+    type_to_unique_id: FnvHashMap<ty::t, UniqueTypeId>
 }
 
 impl TypeMap {
@@ -270,9 +269,9 @@ impl TypeMap {
     fn new() -> TypeMap {
         TypeMap {
             unique_id_interner: Interner::new(),
-            type_to_metadata: HashMap::new(),
-            unique_id_to_metadata: HashMap::new(),
-            type_to_unique_id: HashMap::new(),
+            type_to_metadata: FnvHashMap::new(),
+            unique_id_to_metadata: FnvHashMap::new(),
+            type_to_unique_id: FnvHashMap::new(),
         }
     }
 
@@ -282,7 +281,7 @@ impl TypeMap {
                                    cx: &CrateContext,
                                    type_: ty::t,
                                    metadata: DIType) {
-        if self.type_to_metadata.insert(ty::type_id(type_), metadata).is_some() {
+        if self.type_to_metadata.insert(type_, metadata).is_some() {
             cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!",
                                    ppaux::ty_to_string(cx.tcx(), type_)).as_slice());
         }
@@ -302,7 +301,7 @@ impl TypeMap {
     }
 
     fn find_metadata_for_type(&self, type_: ty::t) -> Option<DIType> {
-        self.type_to_metadata.find_copy(&ty::type_id(type_))
+        self.type_to_metadata.find_copy(&type_)
     }
 
     fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
@@ -342,7 +341,7 @@ impl TypeMap {
         // unique vec box (~[]) -> {HEAP_VEC_BOX<:pointee-uid:>}
         // gc box               -> {GC_BOX<:pointee-uid:>}
 
-        match self.type_to_unique_id.find_copy(&ty::type_id(type_)) {
+        match self.type_to_unique_id.find_copy(&type_) {
             Some(unique_type_id) => return unique_type_id,
             None => { /* generate one */}
         };
@@ -486,7 +485,7 @@ impl TypeMap {
         unique_type_id.shrink_to_fit();
 
         let key = self.unique_id_interner.intern(Rc::new(unique_type_id));
-        self.type_to_unique_id.insert(ty::type_id(type_), UniqueTypeId(key));
+        self.type_to_unique_id.insert(type_, UniqueTypeId(key));
 
         return UniqueTypeId(key);
 
@@ -645,15 +644,15 @@ pub struct CrateDebugContext {
     llcontext: ContextRef,
     builder: DIBuilderRef,
     current_debug_location: Cell<DebugLocation>,
-    created_files: RefCell<HashMap<String, DIFile>>,
-    created_enum_disr_types: RefCell<HashMap<ast::DefId, DIType>>,
+    created_files: RefCell<FnvHashMap<String, DIFile>>,
+    created_enum_disr_types: RefCell<DefIdMap<DIType>>,
 
     type_map: RefCell<TypeMap>,
-    namespace_map: RefCell<HashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
+    namespace_map: RefCell<FnvHashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
 
     // This collection is used to assert that composite types (structs, enums,
     // ...) have their members only set once:
-    composite_types_completed: RefCell<HashSet<DIType>>,
+    composite_types_completed: RefCell<FnvHashSet<DIType>>,
 }
 
 impl CrateDebugContext {
@@ -666,11 +665,11 @@ impl CrateDebugContext {
             llcontext: llcontext,
             builder: builder,
             current_debug_location: Cell::new(UnknownLocation),
-            created_files: RefCell::new(HashMap::new()),
-            created_enum_disr_types: RefCell::new(HashMap::new()),
+            created_files: RefCell::new(FnvHashMap::new()),
+            created_enum_disr_types: RefCell::new(DefIdMap::new()),
             type_map: RefCell::new(TypeMap::new()),
-            namespace_map: RefCell::new(HashMap::new()),
-            composite_types_completed: RefCell::new(HashSet::new()),
+            namespace_map: RefCell::new(FnvHashMap::new()),
+            composite_types_completed: RefCell::new(FnvHashSet::new()),
         };
     }
 }
@@ -714,7 +713,7 @@ impl FunctionDebugContext {
 }
 
 struct FunctionDebugContextData {
-    scope_map: RefCell<HashMap<ast::NodeId, DIScope>>,
+    scope_map: RefCell<NodeMap<DIScope>>,
     fn_metadata: DISubprogram,
     argument_counter: Cell<uint>,
     source_locations_enabled: Cell<bool>,
@@ -1346,7 +1345,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
 
     // Initialize fn debug context (including scope map and namespace map)
     let fn_debug_context = box FunctionDebugContextData {
-        scope_map: RefCell::new(HashMap::new()),
+        scope_map: RefCell::new(NodeMap::new()),
         fn_metadata: fn_metadata,
         argument_counter: Cell::new(1),
         source_locations_enabled: Cell::new(false),
@@ -3122,7 +3121,7 @@ fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
 fn assert_type_for_node_id(cx: &CrateContext,
                            node_id: ast::NodeId,
                            error_reporting_span: Span) {
-    if !cx.tcx().node_types.borrow().contains_key(&(node_id as uint)) {
+    if !cx.tcx().node_types.borrow().contains_key(&node_id) {
         cx.sess().span_bug(error_reporting_span,
                            "debuginfo: Could not find type for node id!");
     }
@@ -3153,7 +3152,7 @@ fn populate_scope_map(cx: &CrateContext,
                       fn_entry_block: &ast::Block,
                       fn_metadata: DISubprogram,
                       fn_ast_id: ast::NodeId,
-                      scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+                      scope_map: &mut NodeMap<DIScope>) {
     let def_map = &cx.tcx().def_map;
 
     struct ScopeStackEntry {
@@ -3188,10 +3187,10 @@ fn populate_scope_map(cx: &CrateContext,
     fn with_new_scope(cx: &CrateContext,
                       scope_span: Span,
                       scope_stack: &mut Vec<ScopeStackEntry> ,
-                      scope_map: &mut HashMap<ast::NodeId, DIScope>,
+                      scope_map: &mut NodeMap<DIScope>,
                       inner_walk: |&CrateContext,
                                    &mut Vec<ScopeStackEntry> ,
-                                   &mut HashMap<ast::NodeId, DIScope>|) {
+                                   &mut NodeMap<DIScope>|) {
         // Create a new lexical scope and push it onto the stack
         let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
         let file_metadata = file_metadata(cx, loc.file.name.as_slice());
@@ -3226,7 +3225,7 @@ fn populate_scope_map(cx: &CrateContext,
     fn walk_block(cx: &CrateContext,
                   block: &ast::Block,
                   scope_stack: &mut Vec<ScopeStackEntry> ,
-                  scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+                  scope_map: &mut NodeMap<DIScope>) {
         scope_map.insert(block.id, scope_stack.last().unwrap().scope_metadata);
 
         // The interesting things here are statements and the concluding expression.
@@ -3252,7 +3251,7 @@ fn populate_scope_map(cx: &CrateContext,
     fn walk_decl(cx: &CrateContext,
                  decl: &ast::Decl,
                  scope_stack: &mut Vec<ScopeStackEntry> ,
-                 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+                 scope_map: &mut NodeMap<DIScope>) {
         match *decl {
             codemap::Spanned { node: ast::DeclLocal(ref local), .. } => {
                 scope_map.insert(local.id, scope_stack.last().unwrap().scope_metadata);
@@ -3270,7 +3269,7 @@ fn populate_scope_map(cx: &CrateContext,
     fn walk_pattern(cx: &CrateContext,
                     pat: &ast::Pat,
                     scope_stack: &mut Vec<ScopeStackEntry> ,
-                    scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+                    scope_map: &mut NodeMap<DIScope>) {
 
         let def_map = &cx.tcx().def_map;
 
@@ -3428,7 +3427,7 @@ fn populate_scope_map(cx: &CrateContext,
     fn walk_expr(cx: &CrateContext,
                  exp: &ast::Expr,
                  scope_stack: &mut Vec<ScopeStackEntry> ,
-                 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
+                 scope_map: &mut NodeMap<DIScope>) {
 
         scope_map.insert(exp.id, scope_stack.last().unwrap().scope_metadata);
 
diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs
index 175b0d7adde..cb6dbcb22e2 100644
--- a/src/librustc/middle/trans/type_.rs
+++ b/src/librustc/middle/trans/type_.rs
@@ -15,13 +15,13 @@ use llvm::{TypeRef, Bool, False, True, TypeKind, ValueRef};
 use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
 
 use middle::trans::context::CrateContext;
+use util::nodemap::FnvHashMap;
 
 use syntax::ast;
 
 use std::c_str::ToCStr;
 use std::mem;
 use std::cell::RefCell;
-use std::collections::HashMap;
 
 use libc::c_uint;
 
@@ -320,13 +320,13 @@ impl Type {
 /* Memory-managed object interface to type handles. */
 
 pub struct TypeNames {
-    named_types: RefCell<HashMap<String, TypeRef>>,
+    named_types: RefCell<FnvHashMap<String, TypeRef>>,
 }
 
 impl TypeNames {
     pub fn new() -> TypeNames {
         TypeNames {
-            named_types: RefCell::new(HashMap::new())
+            named_types: RefCell::new(FnvHashMap::new())
         }
     }
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 1a6e8eeb320..0a3c4e76fa0 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -32,9 +32,9 @@ use middle;
 use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
 use util::ppaux::{trait_store_to_string, ty_to_string};
 use util::ppaux::{Repr, UserString};
-use util::common::{indenter, memoized, memoized_with_key};
-use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet, FnvHashMap};
-
+use util::common::{indenter, memoized};
+use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
+use util::nodemap::{FnvHashMap, FnvHashSet};
 use std::cell::{Cell, RefCell};
 use std::cmp;
 use std::fmt::{mod, Show};
@@ -42,7 +42,6 @@ use std::hash::{Hash, sip, Writer};
 use std::mem;
 use std::ops;
 use std::rc::Rc;
-use std::collections::{HashMap, HashSet};
 use std::collections::hash_map::{Occupied, Vacant};
 use arena::TypedArena;
 use syntax::abi;
@@ -227,8 +226,6 @@ pub struct creader_cache_key {
     pub len: uint
 }
 
-pub type creader_cache = RefCell<HashMap<creader_cache_key, t>>;
-
 pub struct intern_key {
     sty: *const sty,
 }
@@ -438,7 +435,6 @@ pub struct ctxt<'tcx> {
     /// Specifically use a speedy hash algorithm for this hash map, it's used
     /// quite often.
     interner: RefCell<FnvHashMap<intern_key, &'tcx t_box_>>,
-    pub next_id: Cell<uint>,
     pub sess: Session,
     pub def_map: resolve::DefMap,
 
@@ -449,7 +445,7 @@ pub struct ctxt<'tcx> {
     /// Stores the types for various nodes in the AST.  Note that this table
     /// is not guaranteed to be populated until after typeck.  See
     /// typeck::check::fn_ctxt for details.
-    pub node_types: node_type_table,
+    pub node_types: RefCell<NodeMap<t>>,
 
     /// Stores the type parameters which were substituted to obtain the type
     /// of this node.  This only applies to nodes that refer to entities
@@ -478,16 +474,16 @@ pub struct ctxt<'tcx> {
     pub map: ast_map::Map<'tcx>,
     pub intrinsic_defs: RefCell<DefIdMap<t>>,
     pub freevars: RefCell<FreevarMap>,
-    pub tcache: type_cache,
-    pub rcache: creader_cache,
-    pub short_names_cache: RefCell<HashMap<t, String>>,
-    pub needs_unwind_cleanup_cache: RefCell<HashMap<t, bool>>,
-    pub tc_cache: RefCell<HashMap<uint, TypeContents>>,
+    pub tcache: RefCell<DefIdMap<Polytype>>,
+    pub rcache: RefCell<FnvHashMap<creader_cache_key, t>>,
+    pub short_names_cache: RefCell<FnvHashMap<t, String>>,
+    pub needs_unwind_cleanup_cache: RefCell<FnvHashMap<t, bool>>,
+    pub tc_cache: RefCell<FnvHashMap<t, TypeContents>>,
     pub ast_ty_to_ty_cache: RefCell<NodeMap<ast_ty_to_ty_cache_entry>>,
     pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo>>>>>,
     pub ty_param_defs: RefCell<NodeMap<TypeParameterDef>>,
     pub adjustments: RefCell<NodeMap<AutoAdjustment>>,
-    pub normalized_cache: RefCell<HashMap<t, t>>,
+    pub normalized_cache: RefCell<FnvHashMap<t, t>>,
     pub lang_items: middle::lang_items::LanguageItems,
     /// A mapping of fake provided method def_ids to the default implementation
     pub provided_method_sources: RefCell<DefIdMap<ast::DefId>>,
@@ -556,8 +552,8 @@ pub struct ctxt<'tcx> {
     /// expression defining the unboxed closure.
     pub unboxed_closures: RefCell<DefIdMap<UnboxedClosure>>,
 
-    pub node_lint_levels: RefCell<HashMap<(ast::NodeId, lint::LintId),
-                                          lint::LevelSource>>,
+    pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
+                                              lint::LevelSource>>,
 
     /// The types that must be asserted to be the same size for `transmute`
     /// to be valid. We gather up these restrictions in the intrinsicck pass
@@ -603,7 +599,6 @@ pub type t_box = &'static t_box_;
 #[deriving(Show)]
 pub struct t_box_ {
     pub sty: sty,
-    pub id: uint,
     pub flags: TypeFlags,
 }
 
@@ -648,7 +643,6 @@ pub fn type_has_ty_infer(t: t) -> bool { tbox_has_flag(get(t), HAS_TY_INFER) }
 pub fn type_needs_infer(t: t) -> bool {
     tbox_has_flag(get(t), HAS_TY_INFER | HAS_RE_INFER)
 }
-pub fn type_id(t: t) -> uint { get(t).id }
 
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 pub struct BareFnTy {
@@ -861,7 +855,7 @@ pub struct UpvarBorrow {
     pub region: ty::Region,
 }
 
-pub type UpvarBorrowMap = HashMap<UpvarId, UpvarBorrow>;
+pub type UpvarBorrowMap = FnvHashMap<UpvarId, UpvarBorrow>;
 
 impl Region {
     pub fn is_bound(&self) -> bool {
@@ -904,38 +898,34 @@ mod primitives {
     use syntax::ast;
 
     macro_rules! def_prim_ty(
-        ($name:ident, $sty:expr, $id:expr) => (
+        ($name:ident, $sty:expr) => (
             pub static $name: t_box_ = t_box_ {
                 sty: $sty,
-                id: $id,
                 flags: super::NO_TYPE_FLAGS,
             };
         )
     )
 
-    def_prim_ty!(TY_NIL,    super::ty_nil,                  0)
-    def_prim_ty!(TY_BOOL,   super::ty_bool,                 1)
-    def_prim_ty!(TY_CHAR,   super::ty_char,                 2)
-    def_prim_ty!(TY_INT,    super::ty_int(ast::TyI),        3)
-    def_prim_ty!(TY_I8,     super::ty_int(ast::TyI8),       4)
-    def_prim_ty!(TY_I16,    super::ty_int(ast::TyI16),      5)
-    def_prim_ty!(TY_I32,    super::ty_int(ast::TyI32),      6)
-    def_prim_ty!(TY_I64,    super::ty_int(ast::TyI64),      7)
-    def_prim_ty!(TY_UINT,   super::ty_uint(ast::TyU),       8)
-    def_prim_ty!(TY_U8,     super::ty_uint(ast::TyU8),      9)
-    def_prim_ty!(TY_U16,    super::ty_uint(ast::TyU16),     10)
-    def_prim_ty!(TY_U32,    super::ty_uint(ast::TyU32),     11)
-    def_prim_ty!(TY_U64,    super::ty_uint(ast::TyU64),     12)
-    def_prim_ty!(TY_F32,    super::ty_float(ast::TyF32),    14)
-    def_prim_ty!(TY_F64,    super::ty_float(ast::TyF64),    15)
+    def_prim_ty!(TY_NIL,    super::ty_nil)
+    def_prim_ty!(TY_BOOL,   super::ty_bool)
+    def_prim_ty!(TY_CHAR,   super::ty_char)
+    def_prim_ty!(TY_INT,    super::ty_int(ast::TyI))
+    def_prim_ty!(TY_I8,     super::ty_int(ast::TyI8))
+    def_prim_ty!(TY_I16,    super::ty_int(ast::TyI16))
+    def_prim_ty!(TY_I32,    super::ty_int(ast::TyI32))
+    def_prim_ty!(TY_I64,    super::ty_int(ast::TyI64))
+    def_prim_ty!(TY_UINT,   super::ty_uint(ast::TyU))
+    def_prim_ty!(TY_U8,     super::ty_uint(ast::TyU8))
+    def_prim_ty!(TY_U16,    super::ty_uint(ast::TyU16))
+    def_prim_ty!(TY_U32,    super::ty_uint(ast::TyU32))
+    def_prim_ty!(TY_U64,    super::ty_uint(ast::TyU64))
+    def_prim_ty!(TY_F32,    super::ty_float(ast::TyF32))
+    def_prim_ty!(TY_F64,    super::ty_float(ast::TyF64))
 
     pub static TY_ERR: t_box_ = t_box_ {
         sty: super::ty_err,
-        id: 17,
         flags: super::HAS_TY_ERR,
     };
-
-    pub const LAST_PRIMITIVE_ID: uint = 18;
 }
 
 // NB: If you change this, you'll probably want to change the corresponding
@@ -1457,10 +1447,6 @@ pub struct ItemSubsts {
     pub substs: Substs,
 }
 
-pub type type_cache = RefCell<DefIdMap<Polytype>>;
-
-pub type node_type_table = RefCell<HashMap<uint,t>>;
-
 /// Records information about each unboxed closure.
 #[deriving(Clone)]
 pub struct UnboxedClosure {
@@ -1511,11 +1497,10 @@ pub fn mk_ctxt<'tcx>(s: Session,
         named_region_map: named_region_map,
         item_variance_map: RefCell::new(DefIdMap::new()),
         variance_computed: Cell::new(false),
-        next_id: Cell::new(primitives::LAST_PRIMITIVE_ID),
         sess: s,
         def_map: dm,
         region_maps: region_maps,
-        node_types: RefCell::new(HashMap::new()),
+        node_types: RefCell::new(FnvHashMap::new()),
         item_substs: RefCell::new(NodeMap::new()),
         trait_refs: RefCell::new(NodeMap::new()),
         trait_defs: RefCell::new(DefIdMap::new()),
@@ -1524,10 +1509,10 @@ pub fn mk_ctxt<'tcx>(s: Session,
         intrinsic_defs: RefCell::new(DefIdMap::new()),
         freevars: freevars,
         tcache: RefCell::new(DefIdMap::new()),
-        rcache: RefCell::new(HashMap::new()),
-        short_names_cache: RefCell::new(HashMap::new()),
-        needs_unwind_cleanup_cache: RefCell::new(HashMap::new()),
-        tc_cache: RefCell::new(HashMap::new()),
+        rcache: RefCell::new(FnvHashMap::new()),
+        short_names_cache: RefCell::new(FnvHashMap::new()),
+        needs_unwind_cleanup_cache: RefCell::new(FnvHashMap::new()),
+        tc_cache: RefCell::new(FnvHashMap::new()),
         ast_ty_to_ty_cache: RefCell::new(NodeMap::new()),
         enum_var_cache: RefCell::new(DefIdMap::new()),
         impl_or_trait_items: RefCell::new(DefIdMap::new()),
@@ -1536,7 +1521,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         impl_trait_cache: RefCell::new(DefIdMap::new()),
         ty_param_defs: RefCell::new(NodeMap::new()),
         adjustments: RefCell::new(NodeMap::new()),
-        normalized_cache: RefCell::new(HashMap::new()),
+        normalized_cache: RefCell::new(FnvHashMap::new()),
         lang_items: lang_items,
         provided_method_sources: RefCell::new(DefIdMap::new()),
         struct_fields: RefCell::new(DefIdMap::new()),
@@ -1549,13 +1534,13 @@ pub fn mk_ctxt<'tcx>(s: Session,
         used_mut_nodes: RefCell::new(NodeSet::new()),
         populated_external_types: RefCell::new(DefIdSet::new()),
         populated_external_traits: RefCell::new(DefIdSet::new()),
-        upvar_borrow_map: RefCell::new(HashMap::new()),
+        upvar_borrow_map: RefCell::new(FnvHashMap::new()),
         extern_const_statics: RefCell::new(DefIdMap::new()),
         extern_const_variants: RefCell::new(DefIdMap::new()),
         method_map: RefCell::new(FnvHashMap::new()),
-        dependency_formats: RefCell::new(HashMap::new()),
+        dependency_formats: RefCell::new(FnvHashMap::new()),
         unboxed_closures: RefCell::new(DefIdMap::new()),
-        node_lint_levels: RefCell::new(HashMap::new()),
+        node_lint_levels: RefCell::new(FnvHashMap::new()),
         transmute_restrictions: RefCell::new(Vec::new()),
         stability: RefCell::new(stability),
         capture_modes: capture_modes,
@@ -1681,7 +1666,6 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
 
     let t = cx.type_arena.alloc(t_box_ {
         sty: st,
-        id: cx.next_id.get(),
         flags: flags,
     });
 
@@ -1693,8 +1677,6 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
 
     cx.interner.borrow_mut().insert(key, t);
 
-    cx.next_id.set(cx.next_id.get() + 1);
-
     unsafe {
         mem::transmute::<*const sty, t>(sty_ptr)
     }
@@ -2176,10 +2158,10 @@ pub fn type_needs_drop(cx: &ctxt, ty: t) -> bool {
 // cleanups.
 pub fn type_needs_unwind_cleanup(cx: &ctxt, ty: t) -> bool {
     return memoized(&cx.needs_unwind_cleanup_cache, ty, |ty| {
-        type_needs_unwind_cleanup_(cx, ty, &mut HashSet::new())
+        type_needs_unwind_cleanup_(cx, ty, &mut FnvHashSet::new())
     });
 
-    fn type_needs_unwind_cleanup_(cx: &ctxt, ty: t, tycache: &mut HashSet<t>) -> bool {
+    fn type_needs_unwind_cleanup_(cx: &ctxt, ty: t, tycache: &mut FnvHashSet<t>) -> bool {
         // Prevent infinite recursion
         if !tycache.insert(ty) {
             return false;
@@ -2400,13 +2382,13 @@ pub fn type_interior_is_unsafe(cx: &ctxt, t: ty::t) -> bool {
 }
 
 pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
-    return memoized_with_key(&cx.tc_cache, ty, |ty| {
-        tc_ty(cx, ty, &mut HashMap::new())
-    }, |&ty| type_id(ty));
+    return memoized(&cx.tc_cache, ty, |ty| {
+        tc_ty(cx, ty, &mut FnvHashMap::new())
+    });
 
     fn tc_ty(cx: &ctxt,
              ty: t,
-             cache: &mut HashMap<uint, TypeContents>) -> TypeContents
+             cache: &mut FnvHashMap<t, TypeContents>) -> TypeContents
     {
         // Subtle: Note that we are *not* using cx.tc_cache here but rather a
         // private cache for this walk.  This is needed in the case of cyclic
@@ -2429,16 +2411,15 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
         // which is incorrect.  This value was computed based on the crutch
         // value for the type contents of list.  The correct value is
         // TC::OwnsOwned.  This manifested as issue #4821.
-        let ty_id = type_id(ty);
-        match cache.get(&ty_id) {
+        match cache.get(&ty) {
             Some(tc) => { return *tc; }
             None => {}
         }
-        match cx.tc_cache.borrow().get(&ty_id) {    // Must check both caches!
+        match cx.tc_cache.borrow().get(&ty) {    // Must check both caches!
             Some(tc) => { return *tc; }
             None => {}
         }
-        cache.insert(ty_id, TC::None);
+        cache.insert(ty, TC::None);
 
         let result = match get(ty).sty {
             // uint and int are ffi-unsafe
@@ -2608,13 +2589,13 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
             }
         };
 
-        cache.insert(ty_id, result);
-        return result;
+        cache.insert(ty, result);
+        result
     }
 
     fn tc_mt(cx: &ctxt,
              mt: mt,
-             cache: &mut HashMap<uint, TypeContents>) -> TypeContents
+             cache: &mut FnvHashMap<t, TypeContents>) -> TypeContents
     {
         let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable);
         mc | tc_ty(cx, mt.ty, cache)
@@ -2922,7 +2903,7 @@ pub fn is_type_representable(cx: &ctxt, sp: Span, ty: t) -> Representability {
                 pairs.all(|(&a, &b)| same_type(a, b))
             }
             _ => {
-                type_id(a) == type_id(b)
+                a == b
             }
         }
     }
@@ -3213,7 +3194,7 @@ pub fn node_id_to_trait_ref(cx: &ctxt, id: ast::NodeId) -> Rc<ty::TraitRef> {
 }
 
 pub fn try_node_id_to_type(cx: &ctxt, id: ast::NodeId) -> Option<t> {
-    cx.node_types.borrow().find_copy(&(id as uint))
+    cx.node_types.borrow().find_copy(&id)
 }
 
 pub fn node_id_to_type(cx: &ctxt, id: ast::NodeId) -> t {
@@ -3226,7 +3207,7 @@ pub fn node_id_to_type(cx: &ctxt, id: ast::NodeId) -> t {
 }
 
 pub fn node_id_to_type_opt(cx: &ctxt, id: ast::NodeId) -> Option<t> {
-    match cx.node_types.borrow().get(&(id as uint)) {
+    match cx.node_types.borrow().get(&id) {
        Some(&t) => Some(t),
        None => None
     }
@@ -3702,7 +3683,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
         }
 
         ast::ExprCast(..) => {
-            match tcx.node_types.borrow().get(&(expr.id as uint)) {
+            match tcx.node_types.borrow().get(&expr.id) {
                 Some(&t) => {
                     if type_is_trait(t) {
                         RvalueDpsExpr
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index e27ff636a2a..ec289a2d806 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -61,9 +61,9 @@ use middle::typeck::rscope::{UnelidableRscope, RegionScope, SpecificRscope, Bind
 use middle::typeck::rscope;
 use middle::typeck::TypeAndSubsts;
 use middle::typeck;
+use util::nodemap::DefIdMap;
 use util::ppaux::{Repr, UserString};
 
-use std::collections::HashMap;
 use std::rc::Rc;
 use std::iter::AdditiveIterator;
 use syntax::{abi, ast, ast_util};
@@ -1545,7 +1545,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
     let mut builtin_bounds = ty::empty_builtin_bounds();
     let mut region_bounds = Vec::new();
     let mut trait_bounds = Vec::new();
-    let mut trait_def_ids = HashMap::new();
+    let mut trait_def_ids = DefIdMap::new();
     for &ast_bound in ast_bounds.iter() {
         match *ast_bound {
             ast::TraitTyParamBound(ref b) => {
@@ -1599,4 +1599,3 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt,
         region_bounds: region_bounds,
     }
 }
-
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index 7070f16da3b..c15b6e6ddae 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -16,9 +16,9 @@ use middle::typeck::check::{check_expr, check_expr_has_type, demand, FnCtxt};
 use middle::typeck::check::{instantiate_path, structurally_resolved_type, valid_range_bounds};
 use middle::typeck::infer::{mod, resolve};
 use middle::typeck::require_same_types;
+use util::nodemap::FnvHashMap;
 
 use std::cmp;
-use std::collections::HashMap;
 use std::collections::hash_map::{Occupied, Vacant};
 use syntax::ast;
 use syntax::ast_util;
@@ -430,10 +430,10 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
     let field_type_map = struct_fields
         .iter()
         .map(|field| (field.name, field.mt.ty))
-        .collect::<HashMap<_, _>>();
+        .collect::<FnvHashMap<_, _>>();
 
     // Keep track of which fields have already appeared in the pattern.
-    let mut used_fields = HashMap::new();
+    let mut used_fields = FnvHashMap::new();
 
     // Typecheck each field.
     for &Spanned { node: ref field, span } in fields.iter() {
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index ccd6a8103b9..cac702d6ac0 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -117,7 +117,6 @@ use util::ppaux::{UserString, Repr};
 use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
 
 use std::cell::{Cell, Ref, RefCell};
-use std::collections::HashMap;
 use std::collections::hash_map::{Occupied, Vacant};
 use std::mem::replace;
 use std::rc::Rc;
@@ -334,7 +333,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
             adjustments: RefCell::new(NodeMap::new()),
             method_map: RefCell::new(FnvHashMap::new()),
             object_cast_map: RefCell::new(NodeMap::new()),
-            upvar_borrow_map: RefCell::new(HashMap::new()),
+            upvar_borrow_map: RefCell::new(FnvHashMap::new()),
             unboxed_closures: RefCell::new(DefIdMap::new()),
             fn_sig_map: RefCell::new(NodeMap::new()),
             region_obligations: RefCell::new(NodeMap::new()),
@@ -3747,7 +3746,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                                       check_completeness: bool)  {
         let tcx = fcx.ccx.tcx;
 
-        let mut class_field_map = HashMap::new();
+        let mut class_field_map = FnvHashMap::new();
         let mut fields_found = 0;
         for field in field_types.iter() {
             class_field_map.insert(field.name, (field.id, false));
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index d47d5649c65..9aa047e068f 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -132,7 +132,7 @@ use middle::typeck::infer::resolve_type;
 use middle::typeck::infer;
 use middle::typeck::MethodCall;
 use middle::pat_util;
-use util::nodemap::{DefIdMap, NodeMap};
+use util::nodemap::{DefIdMap, NodeMap, FnvHashMap};
 use util::ppaux::{ty_to_string, Repr};
 
 use syntax::ast;
@@ -141,7 +141,6 @@ use syntax::visit;
 use syntax::visit::Visitor;
 
 use std::cell::{RefCell};
-use std::collections::HashMap;
 use std::collections::hash_map::{Vacant, Occupied};
 
 ///////////////////////////////////////////////////////////////////////////
@@ -224,7 +223,7 @@ struct MaybeLink {
 }
 
 // A map associating an upvar ID to a vector of the above
-type MaybeLinkMap = RefCell<HashMap<ty::UpvarId, Vec<MaybeLink>>>;
+type MaybeLinkMap = RefCell<FnvHashMap<ty::UpvarId, Vec<MaybeLink>>>;
 
 pub struct Rcx<'a, 'tcx: 'a> {
     fcx: &'a FnCtxt<'a, 'tcx>,
@@ -270,7 +269,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
         Rcx { fcx: fcx,
               repeating_scope: initial_repeating_scope,
               region_param_pairs: Vec::new(),
-              maybe_links: RefCell::new(HashMap::new()) }
+              maybe_links: RefCell::new(FnvHashMap::new()) }
     }
 
     pub fn tcx(&self) -> &'a ty::ctxt<'tcx> {
diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs
index 91e9c18853c..0856c86946b 100644
--- a/src/librustc/middle/typeck/check/regionmanip.rs
+++ b/src/librustc/middle/typeck/check/regionmanip.rs
@@ -17,8 +17,8 @@ use middle::ty_fold::{TypeFolder, TypeFoldable};
 
 use syntax::ast;
 
-use std::collections::HashMap;
 use std::collections::hash_map::{Occupied, Vacant};
+use util::nodemap::FnvHashMap;
 use util::ppaux::Repr;
 
 // Helper functions related to manipulating region types.
@@ -28,13 +28,13 @@ pub fn replace_late_bound_regions<T>(
     binder_id: ast::NodeId,
     value: &T,
     map_fn: |ty::BoundRegion| -> ty::Region)
-    -> (HashMap<ty::BoundRegion,ty::Region>, T)
+    -> (FnvHashMap<ty::BoundRegion,ty::Region>, T)
     where T : TypeFoldable + Repr
 {
     debug!("replace_late_bound_regions(binder_id={}, value={})",
            binder_id, value.repr(tcx));
 
-    let mut map = HashMap::new();
+    let mut map = FnvHashMap::new();
     let new_value = {
         let mut folder = ty_fold::RegionFolder::regions(tcx, |r| {
             match r {
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index c4e50c25e3e..6685bb9be77 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -48,10 +48,10 @@ use middle::typeck::infer;
 use middle::typeck::rscope::*;
 use middle::typeck::{CrateCtxt, lookup_def_tcx, no_params, write_ty_to_tcx};
 use middle::typeck;
+use util::nodemap::{FnvHashMap, FnvHashSet};
 use util::ppaux;
 use util::ppaux::{Repr,UserString};
 
-use std::collections::{HashMap, HashSet};
 use std::rc::Rc;
 
 use syntax::abi;
@@ -530,7 +530,7 @@ fn convert_methods<'a,I>(ccx: &CrateCtxt,
            rcvr_ty_generics.repr(ccx.tcx));
 
     let tcx = ccx.tcx;
-    let mut seen_methods = HashSet::new();
+    let mut seen_methods = FnvHashSet::new();
     for m in ms {
         if !seen_methods.insert(m.pe_ident().repr(tcx)) {
             tcx.sess.span_err(m.span, "duplicate method in trait impl");
@@ -1247,7 +1247,7 @@ pub fn convert_struct(ccx: &CrateCtxt,
     let tcx = ccx.tcx;
 
     // Write the type of each of the members and check for duplicate fields.
-    let mut seen_fields: HashMap<ast::Name, Span> = HashMap::new();
+    let mut seen_fields: FnvHashMap<ast::Name, Span> = FnvHashMap::new();
     let field_tys = struct_def.fields.iter().map(|f| {
         let result = convert_field(ccx, &pty.generics, f, local_def(id));
 
diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs
index fbf2918c292..7ed5a5db161 100644
--- a/src/librustc/middle/typeck/infer/glb.rs
+++ b/src/librustc/middle/typeck/infer/glb.rs
@@ -24,8 +24,8 @@ use middle::typeck::infer::region_inference::RegionMark;
 use syntax::ast::{Many, Once, MutImmutable, MutMutable};
 use syntax::ast::{NormalFn, UnsafeFn, NodeId};
 use syntax::ast::{Onceness, FnStyle};
-use std::collections::HashMap;
 use util::common::{indenter};
+use util::nodemap::FnvHashMap;
 use util::ppaux::mt_to_string;
 use util::ppaux::Repr;
 
@@ -176,7 +176,7 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
                              mark: RegionMark,
                              new_vars: &[RegionVid],
                              new_binder_id: NodeId,
-                             a_map: &HashMap<ty::BoundRegion, ty::Region>,
+                             a_map: &FnvHashMap<ty::BoundRegion, ty::Region>,
                              a_vars: &[RegionVid],
                              b_vars: &[RegionVid],
                              r0: ty::Region) -> ty::Region {
@@ -243,7 +243,7 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
         }
 
         fn rev_lookup(this: &Glb,
-                      a_map: &HashMap<ty::BoundRegion, ty::Region>,
+                      a_map: &FnvHashMap<ty::BoundRegion, ty::Region>,
                       new_binder_id: NodeId,
                       r: ty::Region) -> ty::Region
         {
diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs
index 4fb7bebc58f..5dbcaadf0df 100644
--- a/src/librustc/middle/typeck/infer/lattice.rs
+++ b/src/librustc/middle/typeck/infer/lattice.rs
@@ -37,10 +37,9 @@ use middle::typeck::infer::*;
 use middle::typeck::infer::combine::*;
 use middle::typeck::infer::glb::Glb;
 use middle::typeck::infer::lub::Lub;
+use util::nodemap::FnvHashMap;
 use util::ppaux::Repr;
 
-use std::collections::HashMap;
-
 pub trait LatticeDir {
     // Relates the type `v` to `a` and `b` such that `v` represents
     // the LUB/GLB of `a` and `b` as appropriate.
@@ -108,7 +107,7 @@ pub fn super_lattice_tys<'tcx, L:LatticeDir+Combine<'tcx>>(this: &L,
 // fn types
 
 pub fn var_ids<'tcx, T: Combine<'tcx>>(this: &T,
-                                       map: &HashMap<ty::BoundRegion, ty::Region>)
+                                       map: &FnvHashMap<ty::BoundRegion, ty::Region>)
                                        -> Vec<RegionVid> {
     map.iter().map(|(_, r)| match *r {
             ty::ReInfer(ty::ReVar(r)) => { r }
diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs
index f2d9203f843..59778340564 100644
--- a/src/librustc/middle/typeck/infer/lub.rs
+++ b/src/librustc/middle/typeck/infer/lub.rs
@@ -20,11 +20,11 @@ use middle::typeck::infer::{cres, InferCtxt};
 use middle::typeck::infer::fold_regions_in_sig;
 use middle::typeck::infer::{TypeTrace, Subtype};
 use middle::typeck::infer::region_inference::RegionMark;
-use std::collections::HashMap;
 use syntax::ast::{Many, Once, NodeId};
 use syntax::ast::{NormalFn, UnsafeFn};
 use syntax::ast::{Onceness, FnStyle};
 use syntax::ast::{MutMutable, MutImmutable};
+use util::nodemap::FnvHashMap;
 use util::ppaux::mt_to_string;
 use util::ppaux::Repr;
 
@@ -151,7 +151,7 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
                              mark: RegionMark,
                              new_vars: &[RegionVid],
                              new_scope: NodeId,
-                             a_map: &HashMap<ty::BoundRegion, ty::Region>,
+                             a_map: &FnvHashMap<ty::BoundRegion, ty::Region>,
                              r0: ty::Region)
                              -> ty::Region {
             // Regions that pre-dated the LUB computation stay as they are.
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index 23000949115..2f6f307494a 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -30,12 +30,12 @@ use middle::ty_fold;
 use middle::ty_fold::{TypeFolder, TypeFoldable};
 use middle::typeck::check::regionmanip::replace_late_bound_regions;
 use std::cell::{RefCell};
-use std::collections::HashMap;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap;
 use syntax::codemap::Span;
 use util::common::indent;
+use util::nodemap::FnvHashMap;
 use util::ppaux::{bound_region_to_string, ty_to_string};
 use util::ppaux::{trait_ref_to_string, Repr};
 
@@ -958,7 +958,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                                          trace: TypeTrace,
                                                          fsig: &ty::FnSig)
                                                     -> (ty::FnSig,
-                                                        HashMap<ty::BoundRegion,
+                                                        FnvHashMap<ty::BoundRegion,
                                                                 ty::Region>) {
         let (map, fn_sig) =
             replace_late_bound_regions(self.tcx, fsig.binder_id, fsig, |br| {
diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs
index 70c4a245b2c..dcf618d94c2 100644
--- a/src/librustc/middle/typeck/infer/region_inference/mod.rs
+++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs
@@ -21,11 +21,11 @@ use middle::typeck::infer;
 use middle::graph;
 use middle::graph::{Direction, NodeIndex};
 use util::common::indenter;
+use util::nodemap::{FnvHashMap, FnvHashSet};
 use util::ppaux::Repr;
 
 use std::cell::{Cell, RefCell};
 use std::uint;
-use std::collections::{HashMap, HashSet};
 use syntax::ast;
 
 mod doc;
@@ -149,7 +149,7 @@ impl SameRegions {
     }
 }
 
-pub type CombineMap = HashMap<TwoRegions, RegionVid>;
+pub type CombineMap = FnvHashMap<TwoRegions, RegionVid>;
 
 pub struct RegionVarBindings<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
@@ -158,7 +158,7 @@ pub struct RegionVarBindings<'a, 'tcx: 'a> {
     // Constraints of the form `A <= B` introduced by the region
     // checker.  Here at least one of `A` and `B` must be a region
     // variable.
-    constraints: RefCell<HashMap<Constraint, SubregionOrigin>>,
+    constraints: RefCell<FnvHashMap<Constraint, SubregionOrigin>>,
 
     // A "verify" is something that we need to verify after inference is
     // done, but which does not directly affect inference in any way.
@@ -184,7 +184,7 @@ pub struct RegionVarBindings<'a, 'tcx: 'a> {
     // record the fact that `'a <= 'b` is implied by the fn signature,
     // and then ignore the constraint when solving equations. This is
     // a bit of a hack but seems to work.
-    givens: RefCell<HashSet<(ty::FreeRegion, ty::RegionVid)>>,
+    givens: RefCell<FnvHashSet<(ty::FreeRegion, ty::RegionVid)>>,
 
     lubs: RefCell<CombineMap>,
     glbs: RefCell<CombineMap>,
@@ -223,11 +223,11 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
             tcx: tcx,
             var_origins: RefCell::new(Vec::new()),
             values: RefCell::new(None),
-            constraints: RefCell::new(HashMap::new()),
+            constraints: RefCell::new(FnvHashMap::new()),
             verifys: RefCell::new(Vec::new()),
-            givens: RefCell::new(HashSet::new()),
-            lubs: RefCell::new(HashMap::new()),
-            glbs: RefCell::new(HashMap::new()),
+            givens: RefCell::new(FnvHashSet::new()),
+            lubs: RefCell::new(FnvHashMap::new()),
+            glbs: RefCell::new(FnvHashMap::new()),
             skolemization_count: Cell::new(0),
             bound_count: Cell::new(0),
             undo_log: RefCell::new(Vec::new())
@@ -1183,7 +1183,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                                       values: &Vec<VarValue>,
                                       errors: &mut Vec<RegionResolutionError>)
     {
-        let mut reg_reg_dups = HashSet::new();
+        let mut reg_reg_dups = FnvHashSet::new();
         for verify in self.verifys.borrow().iter() {
             match *verify {
                 VerifyRegSubReg(ref origin, sub, sup) => {
@@ -1453,13 +1453,13 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
                                 dup_vec: &mut [uint])
                                 -> (Vec<RegionAndOrigin> , bool) {
         struct WalkState {
-            set: HashSet<RegionVid>,
+            set: FnvHashSet<RegionVid>,
             stack: Vec<RegionVid> ,
             result: Vec<RegionAndOrigin> ,
             dup_found: bool
         }
         let mut state = WalkState {
-            set: HashSet::new(),
+            set: FnvHashSet::new(),
             stack: vec!(orig_node_idx),
             result: Vec::new(),
             dup_found: false
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 5ca0de47ad5..f348e6155a2 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -285,8 +285,9 @@ pub struct CrateCtxt<'a, 'tcx: 'a> {
 pub fn write_ty_to_tcx(tcx: &ty::ctxt, node_id: ast::NodeId, ty: ty::t) {
     debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_string(tcx, ty));
     assert!(!ty::type_needs_infer(ty));
-    tcx.node_types.borrow_mut().insert(node_id as uint, ty);
+    tcx.node_types.borrow_mut().insert(node_id, ty);
 }
+
 pub fn write_substs_to_tcx(tcx: &ty::ctxt,
                            node_id: ast::NodeId,
                            item_substs: ty::ItemSubsts) {
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index b6d8c85fa0b..3a2dc1d5ff0 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -192,7 +192,6 @@ represents the "variance transform" as defined in the paper:
 
 */
 
-use std::collections::HashMap;
 use arena;
 use arena::Arena;
 use middle::resolve_lifetime as rl;
@@ -206,6 +205,7 @@ use syntax::ast_map;
 use syntax::ast_util;
 use syntax::visit;
 use syntax::visit::Visitor;
+use util::nodemap::NodeMap;
 use util::ppaux::Repr;
 
 pub fn infer_variance(tcx: &ty::ctxt) {
@@ -263,7 +263,7 @@ struct TermsContext<'a, 'tcx: 'a> {
 
     // Maps from the node id of a type/generic parameter to the
     // corresponding inferred index.
-    inferred_map: HashMap<ast::NodeId, InferredIndex>,
+    inferred_map: NodeMap<InferredIndex>,
 
     // Maps from an InferredIndex to the info for that variable.
     inferred_infos: Vec<InferredInfo<'a>> ,
@@ -291,7 +291,7 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
     let mut terms_cx = TermsContext {
         tcx: tcx,
         arena: arena,
-        inferred_map: HashMap::new(),
+        inferred_map: NodeMap::new(),
         inferred_infos: Vec::new(),
 
         // cache and share the variance struct used for items with
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 577d92744e6..9d94f4d2356 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -189,17 +189,7 @@ pub fn memoized<T: Clone + Hash<S> + Eq, U: Clone, S, H: Hasher<S>>(
     arg: T,
     f: |T| -> U
 ) -> U {
-    memoized_with_key(cache, arg, f, |arg| arg.clone())
-}
-
-#[inline(always)]
-pub fn memoized_with_key<T, K: Hash<S> + Eq, U: Clone, S, H: Hasher<S>>(
-    cache: &RefCell<HashMap<K, U, H>>,
-    arg: T,
-    f: |T| -> U,
-    k: |&T| -> K
-) -> U {
-    let key = k(&arg);
+    let key = arg.clone();
     let result = cache.borrow().get(&key).map(|result| result.clone());
     match result {
         Some(result) => result,
diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs
index 75406eb29a9..4dd6306c3c0 100644
--- a/src/librustc/util/nodemap.rs
+++ b/src/librustc/util/nodemap.rs
@@ -68,7 +68,7 @@ pub mod DefIdSet {
 ///
 /// This uses FNV hashing, as described here:
 /// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
-#[deriving(Clone)]
+#[deriving(Clone, Default)]
 pub struct FnvHasher;
 
 pub struct FnvState(u64);