diff --git a/src/Cargo.lock b/src/Cargo.lock
index fe67a1655f18..b40e04354931 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -1110,6 +1110,11 @@ dependencies = [
  "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "ordermap"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "owning_ref"
 version = "0.3.3"
@@ -1431,6 +1436,7 @@ dependencies = [
  "graphviz 0.0.0",
  "jobserver 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_back 0.0.0",
  "rustc_const_math 0.0.0",
@@ -1546,6 +1552,7 @@ name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
 ]
 
@@ -1610,6 +1617,7 @@ name = "rustc_lint"
 version = "0.0.0"
 dependencies = [
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_const_eval 0.0.0",
@@ -1644,6 +1652,7 @@ version = "0.0.0"
 dependencies = [
  "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
  "rustc 0.0.0",
@@ -1663,6 +1672,7 @@ dependencies = [
  "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_const_eval 0.0.0",
  "rustc_const_math 0.0.0",
@@ -1689,6 +1699,7 @@ name = "rustc_passes"
 version = "0.0.0"
 dependencies = [
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_const_eval 0.0.0",
  "rustc_const_math 0.0.0",
@@ -1760,6 +1771,7 @@ dependencies = [
  "jobserver 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1809,6 +1821,7 @@ dependencies = [
  "arena 0.0.0",
  "fmt_macros 0.0.0",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_const_math 0.0.0",
@@ -1953,6 +1966,9 @@ dependencies = [
 [[package]]
 name = "serialize"
 version = "0.0.0"
+dependencies = [
+ "ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
 
 [[package]]
 name = "shell-escape"
@@ -2565,6 +2581,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum openssl 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)" = "816914b22eb15671d62c73442a51978f311e911d6a6f6cbdafa6abce1b5038fc"
 "checksum openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d98df0270d404ccd3c050a41d579c52d1db15375168bb3471e04ec0f5f378daf"
 "checksum openssl-sys 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4c63a7d559c1e5afa6d6a9e6fa34bbc5f800ffc9ae08b72c605420b0c4f5e8"
+"checksum ordermap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c7790b1bc9bf27776cd5cdeaae1263758c2c597d4ae02b58aa63c320f94d778"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
 "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
 "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8"
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 0b62e1bd5afb..06a03e3675dd 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -23,6 +23,7 @@ rustc_errors = { path = "../librustc_errors" }
 serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
+ordermap = "0.3.0"
 
 # Note that these dependencies are a lie, they're just here to get linkage to
 # work.
diff --git a/src/librustc/dep_graph/query.rs b/src/librustc/dep_graph/query.rs
index ea83a4f8b310..97ab2ae4532e 100644
--- a/src/librustc/dep_graph/query.rs
+++ b/src/librustc/dep_graph/query.rs
@@ -41,7 +41,7 @@ impl DepGraphQuery {
     }
 
     pub fn contains_node(&self, node: &DepNode) -> bool {
-        self.indices.contains_key(&node)
+        self.indices.contains_key(node)
     }
 
     pub fn nodes(&self) -> Vec<&DepNode> {
@@ -83,7 +83,7 @@ impl DepGraphQuery {
 
     /// Just the outgoing edges from `node`.
     pub fn immediate_successors(&self, node: &DepNode) -> Vec<&DepNode> {
-        if let Some(&index) = self.indices.get(&node) {
+        if let Some(&index) = self.indices.get(node) {
             self.graph.successor_nodes(index)
                       .map(|s| self.graph.node_data(s))
                       .collect()
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index e7a26e14db5b..3cf2c869b99c 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -21,7 +21,7 @@ use session::Session;
 use std::cmp::Ord;
 use std::hash as std_hash;
 use std::cell::RefCell;
-use std::collections::HashMap;
+use ordermap::OrderMap;
 
 use syntax::ast;
 use syntax::attr;
@@ -426,7 +426,7 @@ pub fn hash_stable_trait_impls<'gcx, W, R>(
     hcx: &mut StableHashingContext<'gcx>,
     hasher: &mut StableHasher<W>,
     blanket_impls: &Vec<DefId>,
-    non_blanket_impls: &HashMap<fast_reject::SimplifiedType, Vec<DefId>, R>)
+    non_blanket_impls: &OrderMap<fast_reject::SimplifiedType, Vec<DefId>, R>)
     where W: StableHasherResult,
           R: std_hash::BuildHasher,
 {
diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs
index c274f8bda9fb..6e9f0ac4ffc4 100644
--- a/src/librustc/infer/freshen.rs
+++ b/src/librustc/infer/freshen.rs
@@ -47,7 +47,7 @@ use ty::subst::Substs;
 use util::nodemap::FxHashMap;
 use hir::def_id::DefId;
 
-use std::collections::hash_map::Entry;
+use ordermap::Entry;
 
 use super::InferCtxt;
 use super::unify_key::ToType;
diff --git a/src/librustc/infer/region_inference/graphviz.rs b/src/librustc/infer/region_inference/graphviz.rs
index 5cf6aa350bdd..bd56ab8e743b 100644
--- a/src/librustc/infer/region_inference/graphviz.rs
+++ b/src/librustc/infer/region_inference/graphviz.rs
@@ -28,7 +28,7 @@ use infer::region_inference::RegionVarBindings;
 use util::nodemap::{FxHashMap, FxHashSet};
 
 use std::borrow::Cow;
-use std::collections::hash_map::Entry::Vacant;
+use ordermap::Entry::Vacant;
 use std::env;
 use std::fs::File;
 use std::io;
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 015dbbb7affa..96429fbd6bfd 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -62,6 +62,7 @@
 
 #![recursion_limit="256"]
 
+extern crate ordermap;
 extern crate arena;
 #[macro_use] extern crate bitflags;
 extern crate core;
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 00f0672822fc..41cf5df68a9c 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -1263,7 +1263,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         let trait_ref = &cache_fresh_trait_pred.0.trait_ref;
         if self.can_use_global_caches(param_env) {
             let cache = tcx.selection_cache.hashmap.borrow();
-            if let Some(cached) = cache.get(&trait_ref) {
+            if let Some(cached) = cache.get(trait_ref) {
                 return Some(cached.get(tcx));
             }
         }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 740299b91f11..eb00ce248ef3 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -53,6 +53,7 @@ use rustc_data_structures::accumulate_vec::AccumulateVec;
 use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
                                            StableHasher, StableHasherResult,
                                            StableVec};
+use rustc_data_structures;
 use arena::{TypedArena, DroplessArena};
 use rustc_const_math::{ConstInt, ConstUsize};
 use rustc_data_structures::indexed_vec::IndexVec;
@@ -60,8 +61,8 @@ use std::any::Any;
 use std::borrow::Borrow;
 use std::cell::{Cell, RefCell};
 use std::cmp::Ordering;
-use std::collections::hash_map::{self, Entry};
-use std::hash::{Hash, Hasher};
+use ordermap::{self, Entry};
+use std::hash::{BuildHasherDefault, Hash, Hasher};
 use std::mem;
 use std::ops::Deref;
 use std::iter;
@@ -275,7 +276,7 @@ impl<'a, V> LocalTableInContext<'a, V> {
         self.data.get(&id.local_id)
     }
 
-    pub fn iter(&self) -> hash_map::Iter<hir::ItemLocalId, V> {
+    pub fn iter(&self) -> ordermap::Iter<hir::ItemLocalId, V> {
         self.data.iter()
     }
 }
@@ -299,7 +300,10 @@ impl<'a, V> LocalTableInContextMut<'a, V> {
         self.data.get_mut(&id.local_id)
     }
 
-    pub fn entry(&mut self, id: hir::HirId) -> Entry<hir::ItemLocalId, V> {
+    pub fn entry(
+        &mut self,
+        id: hir::HirId
+    ) -> Entry<hir::ItemLocalId, V, BuildHasherDefault<rustc_data_structures::fx::FxHasher>> {
         validate_hir_id_for_typeck_tables(self.local_id_root, id, true);
         self.data.entry(id.local_id)
     }
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index 343b1ed68b80..d4604b5de83f 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -11,3 +11,4 @@ crate-type = ["dylib"]
 [dependencies]
 log = "0.3"
 serialize = { path = "../libserialize" }
+ordermap = "0.3.0"
diff --git a/src/librustc_data_structures/fx.rs b/src/librustc_data_structures/fx.rs
index 5bf25437763c..6263929a3d4d 100644
--- a/src/librustc_data_structures/fx.rs
+++ b/src/librustc_data_structures/fx.rs
@@ -8,17 +8,20 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::collections::{HashMap, HashSet};
+use std::collections::HashSet;
 use std::default::Default;
 use std::hash::{Hasher, Hash, BuildHasherDefault};
 use std::ops::BitXor;
+use ordermap::OrderMap;
 
-pub type FxHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>;
+// pub type FxHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>;
 pub type FxHashSet<V> = HashSet<V, BuildHasherDefault<FxHasher>>;
 
+pub type FxHashMap<K, V> = OrderMap<K, V, BuildHasherDefault<FxHasher>>;
+
 #[allow(non_snake_case)]
 pub fn FxHashMap<K: Hash + Eq, V>() -> FxHashMap<K, V> {
-    HashMap::default()
+    Default::default()
 }
 
 #[allow(non_snake_case)]
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 47061883425e..74bcd20c3dee 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -40,6 +40,7 @@ extern crate log;
 extern crate serialize as rustc_serialize; // used by deriving
 #[cfg(unix)]
 extern crate libc;
+extern crate ordermap;
 
 pub use rustc_serialize::hex::ToHex;
 
diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 02cae52166ac..e3d8173f1e47 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -18,7 +18,7 @@
 use fx::{FxHashMap, FxHashSet};
 
 use std::cell::Cell;
-use std::collections::hash_map::Entry;
+use super::ordermap::Entry;
 use std::fmt::Debug;
 use std::hash;
 use std::marker::PhantomData;
diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs
index 9aba48c5bef0..22138ca6b0a6 100644
--- a/src/librustc_data_structures/stable_hasher.rs
+++ b/src/librustc_data_structures/stable_hasher.rs
@@ -13,6 +13,7 @@ use std::marker::PhantomData;
 use std::mem;
 use blake2b::Blake2bHasher;
 use rustc_serialize::leb128;
+use ordermap::OrderMap;
 
 fn write_unsigned_leb128_to_buf(buf: &mut [u8; 16], value: u64) -> usize {
     leb128::write_unsigned_leb128_to(value as u128, |i, v| buf[i] = v)
@@ -482,7 +483,7 @@ impl<I: ::indexed_vec::Idx, CTX> HashStable<CTX> for ::indexed_set::IdxSetBuf<I>
 impl_stable_hash_via_hash!(::std::path::Path);
 impl_stable_hash_via_hash!(::std::path::PathBuf);
 
-impl<K, V, R, HCX> HashStable<HCX> for ::std::collections::HashMap<K, V, R>
+impl<K, V, R, HCX> HashStable<HCX> for OrderMap<K, V, R>
     where K: ToStableHashKey<HCX> + Eq + Hash,
           V: HashStable<HCX>,
           R: BuildHasher,
@@ -542,7 +543,7 @@ impl<K, HCX> HashStable<HCX> for ::std::collections::BTreeSet<K>
 pub fn hash_stable_hashmap<HCX, K, V, R, SK, F, W>(
     hcx: &mut HCX,
     hasher: &mut StableHasher<W>,
-    map: &::std::collections::HashMap<K, V, R>,
+    map: &OrderMap<K, V, R>,
     to_stable_hash_key: F)
     where K: Eq + Hash,
           V: HashStable<HCX>,
diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml
index c3c5461ff7c5..f0bb78e74985 100644
--- a/src/librustc_lint/Cargo.toml
+++ b/src/librustc_lint/Cargo.toml
@@ -16,3 +16,4 @@ rustc_back = { path = "../librustc_back" }
 rustc_const_eval = { path = "../librustc_const_eval" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
+ordermap = "0.3.0"
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index fbf993f45576..d7bf77baf5b2 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -41,6 +41,7 @@ extern crate log;
 extern crate rustc_back;
 extern crate rustc_const_eval;
 extern crate syntax_pos;
+extern crate ordermap;
 
 use rustc::lint;
 use rustc::middle;
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index e2ade19b6e28..6f8b318d7937 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -15,7 +15,7 @@ use util::nodemap::FxHashMap;
 use lint::{LateContext, EarlyContext, LintContext, LintArray};
 use lint::{LintPass, EarlyLintPass, LateLintPass};
 
-use std::collections::hash_map::Entry::{Occupied, Vacant};
+use ordermap::Entry::{Occupied, Vacant};
 
 use syntax::ast;
 use syntax::attr;
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
index 40b75be36fef..dd37d804780b 100644
--- a/src/librustc_metadata/Cargo.toml
+++ b/src/librustc_metadata/Cargo.toml
@@ -21,3 +21,4 @@ serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_ext = { path = "../libsyntax_ext" }
 syntax_pos = { path = "../libsyntax_pos" }
+ordermap = "0.3.0"
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 8eacc21ab003..b491b3811cf4 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -290,7 +290,7 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
         // external item to be parents).
         visible_parent_map: |tcx, cnum| {
             use std::collections::vec_deque::VecDeque;
-            use std::collections::hash_map::Entry;
+            use ordermap::Entry;
 
             assert_eq!(cnum, LOCAL_CRATE);
             let mut visible_parent_map: DefIdMap<DefId> = DefIdMap();
@@ -313,7 +313,7 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
                     }
 
                     match visible_parent_map.entry(child) {
-                        Entry::Occupied(mut entry) => {
+                        Entry::Occupied(entry) => {
                             // If `child` is defined in crate `cnum`, ensure
                             // that it is mapped to a parent in `cnum`.
                             if child.krate == cnum && entry.get().krate != cnum {
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 54dbb68667b3..ac734a0613ba 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -39,6 +39,7 @@ extern crate proc_macro;
 extern crate rustc;
 extern crate rustc_back;
 extern crate rustc_data_structures;
+extern crate ordermap;
 
 mod diagnostics;
 
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index b7a576babeb6..3eb2999fcd17 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -20,3 +20,4 @@ rustc_errors = { path = "../librustc_errors" }
 serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
+ordermap = "0.3.0"
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index 9321121fe155..05c778465a8b 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -117,7 +117,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
     }
 
     pub fn region_span(&self, region: &Region) -> Span {
-        let opt_span = self.region_span_map.get(region);
+        let opt_span = self.region_span_map.get(*region);
         assert!(opt_span.is_some(), "end region not found for {:?}", region);
         *opt_span.unwrap()
     }
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 0790d937cebf..ecea9c04d3fd 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -16,7 +16,7 @@ use rustc_data_structures::indexed_vec::{IndexVec};
 
 use syntax::codemap::DUMMY_SP;
 
-use std::collections::hash_map::Entry;
+use ordermap::Entry;
 use std::mem;
 
 use super::abs_domain::Lift;
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 7e4206e14c56..7acba65ef2ef 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -41,6 +41,7 @@ extern crate syntax_pos;
 extern crate rustc_const_math;
 extern crate rustc_const_eval;
 extern crate core; // for NonZero
+extern crate ordermap;
 
 mod diagnostics;
 
diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml
index d2560c2f8203..87ead4b36ac0 100644
--- a/src/librustc_passes/Cargo.toml
+++ b/src/librustc_passes/Cargo.toml
@@ -16,3 +16,4 @@ rustc_const_math = { path = "../librustc_const_math" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_errors = { path = "../librustc_errors" }
+ordermap = "0.3.0"
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs
index 547d63fc3d4a..8a3dd233653a 100644
--- a/src/librustc_passes/consts.rs
+++ b/src/librustc_passes/consts.rs
@@ -50,7 +50,7 @@ use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 
-use std::collections::hash_map::Entry;
+use ordermap::Entry;
 use std::cmp::Ordering;
 
 struct CheckCrateVisitor<'a, 'tcx: 'a> {
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 28b99e1185bd..52d9e331cf5e 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -32,6 +32,7 @@ extern crate log;
 extern crate syntax;
 extern crate syntax_pos;
 extern crate rustc_errors as errors;
+extern crate ordermap;
 
 mod diagnostics;
 
diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml
index 482350d04b5a..fc2516acd18d 100644
--- a/src/librustc_trans/Cargo.toml
+++ b/src/librustc_trans/Cargo.toml
@@ -30,6 +30,7 @@ rustc_trans_utils = { path = "../librustc_trans_utils" }
 serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
+ordermap = "0.3.0"
 
 [target."cfg(windows)".dependencies]
 cc = "1.0"
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 2b1c62c7f1c7..21ac6a40c69e 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -54,6 +54,7 @@ extern crate rustc_trans_utils;
 extern crate rustc_demangle;
 extern crate jobserver;
 extern crate num_cpus;
+extern crate ordermap;
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs
index 386806e4c9c9..36565ec1151c 100644
--- a/src/librustc_trans/partitioning.rs
+++ b/src/librustc_trans/partitioning.rs
@@ -111,7 +111,7 @@ use rustc::middle::trans::{Linkage, Visibility};
 use rustc::ty::{self, TyCtxt, InstanceDef};
 use rustc::ty::item_path::characteristic_def_id_of_type;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
-use std::collections::hash_map::Entry;
+use ordermap::Entry;
 use syntax::ast::NodeId;
 use syntax::symbol::{Symbol, InternedString};
 use trans_item::{TransItem, TransItemExt, InstantiationMode};
@@ -398,7 +398,7 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<
         let mut smallest = codegen_units.pop().unwrap();
         let second_smallest = codegen_units.last_mut().unwrap();
 
-        for (k, v) in smallest.items_mut().drain() {
+        for (k, v) in smallest.items_mut().drain(..) {
             second_smallest.items_mut().insert(k, v);
         }
     }
diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml
index 194d37dcb81c..7e133beb1911 100644
--- a/src/librustc_typeck/Cargo.toml
+++ b/src/librustc_typeck/Cargo.toml
@@ -21,3 +21,4 @@ rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_errors = { path = "../librustc_errors" }
+ordermap = "0.3.0"
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index ab8994bcae25..a7d37e8c4ffd 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -19,7 +19,7 @@ use check::{FnCtxt, Expectation, Diverges};
 use check::coercion::CoerceMany;
 use util::nodemap::FxHashMap;
 
-use std::collections::hash_map::Entry::{Occupied, Vacant};
+use ordermap::Entry::{Occupied, Vacant};
 use std::cmp;
 use syntax::ast;
 use syntax::codemap::Spanned;
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index af1297697c24..9c05ee52e1e7 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -81,7 +81,7 @@ pub fn resolve_interior<'a, 'gcx, 'tcx>(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
     let region_expr_count = visitor.region_scope_tree.body_expr_count(body_id).unwrap();
     assert_eq!(region_expr_count, visitor.expr_count);
 
-    let mut types: Vec<_> = visitor.types.drain().collect();
+    let mut types: Vec<_> = visitor.types.drain(..).collect();
 
     // Sort types by insertion order
     types.sort_by_key(|t| t.1);
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 9c6a4abfbd7c..d7df3b710dbd 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -108,7 +108,7 @@ use util::common::{ErrorReported, indenter};
 use util::nodemap::{DefIdMap, FxHashMap, NodeMap};
 
 use std::cell::{Cell, RefCell, Ref, RefMut};
-use std::collections::hash_map::Entry;
+use ordermap::Entry;
 use std::cmp;
 use std::fmt::Display;
 use std::mem::replace;
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index d179b390a291..e58df9cbcc46 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -54,7 +54,7 @@ use rustc::hir::def_id::DefIndex;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::util::nodemap::FxHashMap;
 
-use std::collections::hash_map::Entry;
+use ordermap::Entry;
 
 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     pub fn closure_analyze(&self, body: &'gcx hir::Body) {
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 15708ab766ae..4a26300d8577 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -24,7 +24,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::def_id::DefId;
 use rustc::ty::{self, TyCtxt};
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
-use std::collections::hash_map::Entry::{Occupied, Vacant};
+use ordermap::Entry::{Occupied, Vacant};
 
 use syntax_pos::Span;
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 7a6ee73b9b9e..a86cb011c11d 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -90,6 +90,7 @@ extern crate rustc_back;
 extern crate rustc_const_math;
 extern crate rustc_data_structures;
 extern crate rustc_errors as errors;
+extern crate ordermap;
 
 use rustc::hir;
 use rustc::lint;
diff --git a/src/libserialize/Cargo.toml b/src/libserialize/Cargo.toml
index a896c4a634c3..7a08dc48cd8b 100644
--- a/src/libserialize/Cargo.toml
+++ b/src/libserialize/Cargo.toml
@@ -7,3 +7,6 @@ version = "0.0.0"
 name = "serialize"
 path = "lib.rs"
 crate-type = ["dylib", "rlib"]
+
+[dependencies]
+ordermap = "0.3.0"
diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs
index 1a995276931d..6885fa8d1133 100644
--- a/src/libserialize/collection_impls.rs
+++ b/src/libserialize/collection_impls.rs
@@ -14,6 +14,7 @@ use std::hash::{Hash, BuildHasher};
 
 use {Decodable, Encodable, Decoder, Encoder};
 use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet};
+use ordermap::OrderMap;
 
 impl<
     T: Encodable
@@ -163,6 +164,43 @@ impl<K, V, S> Decodable for HashMap<K, V, S>
     }
 }
 
+impl<K, V, S> Encodable for OrderMap<K, V, S>
+    where K: Encodable + Hash + Eq,
+          V: Encodable,
+          S: BuildHasher,
+{
+    fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
+        e.emit_map(self.len(), |e| {
+            let mut i = 0;
+            for (key, val) in self {
+                e.emit_map_elt_key(i, |e| key.encode(e))?;
+                e.emit_map_elt_val(i, |e| val.encode(e))?;
+                i += 1;
+            }
+            Ok(())
+        })
+    }
+}
+
+impl<K, V, S> Decodable for OrderMap<K, V, S>
+    where K: Decodable + Hash + Eq,
+          V: Decodable,
+          S: BuildHasher + Default,
+{
+    fn decode<D: Decoder>(d: &mut D) -> Result<OrderMap<K, V, S>, D::Error> {
+        d.read_map(|d, len| {
+            let state = Default::default();
+            let mut map = OrderMap::with_capacity_and_hasher(len, state);
+            for i in 0..len {
+                let key = d.read_map_elt_key(i, |d| Decodable::decode(d))?;
+                let val = d.read_map_elt_val(i, |d| Decodable::decode(d))?;
+                map.insert(key, val);
+            }
+            Ok(map)
+        })
+    }
+}
+
 impl<T, S> Encodable for HashSet<T, S>
     where T: Encodable + Hash + Eq,
           S: BuildHasher,
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 2e354252c157..43b7bef755be 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -27,6 +27,8 @@ Core encoding and decoding interfaces.
 #![feature(specialization)]
 #![cfg_attr(test, feature(test))]
 
+extern crate ordermap;
+
 pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
 
 pub use self::serialize::{SpecializationError, SpecializedEncoder, SpecializedDecoder};