From d017466d103d2b155d3ef645c538c03e3008ac95 Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Mon, 23 Oct 2017 18:44:58 +0200
Subject: [PATCH 1/2] Use 128 bit instead of Symbol for crate disambiguator

---
 src/librustc/hir/map/collector.rs        |  3 ++-
 src/librustc/hir/map/mod.rs              |  2 +-
 src/librustc/middle/cstore.rs            |  4 ++--
 src/librustc/session/mod.rs              | 17 ++++++++++-------
 src/librustc/ty/context.rs               |  2 +-
 src/librustc/ty/maps/mod.rs              |  3 ++-
 src/librustc/ty/mod.rs                   |  4 ++--
 src/librustc_driver/driver.rs            | 18 ++++++++----------
 src/librustc_incremental/persist/fs.rs   | 15 +++++----------
 src/librustc_metadata/creader.rs         |  3 ++-
 src/librustc_metadata/cstore.rs          |  3 ++-
 src/librustc_metadata/cstore_impl.rs     |  3 ++-
 src/librustc_metadata/schema.rs          |  4 ++--
 src/librustc_resolve/lib.rs              |  2 +-
 src/librustc_trans/back/symbol_export.rs |  2 +-
 src/librustc_trans/back/symbol_names.rs  |  2 +-
 16 files changed, 44 insertions(+), 43 deletions(-)

diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 80fadcda2775d..10900624d9283 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -11,6 +11,7 @@
 use super::*;
 
 use dep_graph::{DepGraph, DepKind, DepNodeIndex};
+use ich::Fingerprint;
 use hir::intravisit::{Visitor, NestedVisitorMap};
 use std::iter::repeat;
 use syntax::ast::{NodeId, CRATE_NODE_ID};
@@ -118,7 +119,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
     }
 
     pub(super) fn finalize_and_compute_crate_hash(self,
-                                                  crate_disambiguator: &str)
+                                                  crate_disambiguator: &Fingerprint)
                                                   -> Vec<MapEntry<'hir>> {
         let mut node_hashes: Vec<_> = self
             .hir_body_nodes
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 8ce2feab06cef..6da612fbaa684 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -1014,7 +1014,7 @@ pub fn map_crate<'hir>(sess: &::session::Session,
                                                 hcx);
         intravisit::walk_crate(&mut collector, &forest.krate);
 
-        let crate_disambiguator = sess.local_crate_disambiguator().as_str();
+        let crate_disambiguator = sess.local_crate_disambiguator();
         collector.finalize_and_compute_crate_hash(&crate_disambiguator)
     };
 
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index a97bfa0536987..39b2162bd328b 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -267,7 +267,7 @@ pub trait CrateStore {
     fn export_macros_untracked(&self, cnum: CrateNum);
     fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind;
     fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
-    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> Symbol;
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> ich::Fingerprint;
     fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
     fn struct_field_names_untracked(&self, def: DefId) -> Vec<ast::Name>;
     fn item_children_untracked(&self, did: DefId, sess: &Session) -> Vec<def::Export>;
@@ -338,7 +338,7 @@ impl CrateStore for DummyCrateStore {
     fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") }
     fn export_macros_untracked(&self, cnum: CrateNum) { bug!("export_macros") }
     fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol { bug!("crate_name") }
-    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> Symbol {
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> ich::Fingerprint {
         bug!("crate_disambiguator")
     }
     fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 2634ab1000703..23fea747f769e 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -12,6 +12,7 @@ pub use self::code_stats::{CodeStats, DataTypeKind, FieldInfo};
 pub use self::code_stats::{SizeKind, TypeSizeInfo, VariantInfo};
 
 use hir::def_id::{CrateNum, DefIndex};
+use ich::Fingerprint;
 
 use lint;
 use middle::allocator::AllocatorKind;
@@ -29,7 +30,6 @@ use syntax::json::JsonEmitter;
 use syntax::feature_gate;
 use syntax::parse;
 use syntax::parse::ParseSess;
-use syntax::symbol::Symbol;
 use syntax::{ast, codemap};
 use syntax::feature_gate::AttributeType;
 use syntax_pos::{Span, MultiSpan};
@@ -88,7 +88,7 @@ pub struct Session {
     /// forms a unique global identifier for the crate. It is used to allow
     /// multiple crates with the same name to coexist. See the
     /// trans::back::symbol_names module for more information.
-    pub crate_disambiguator: RefCell<Option<Symbol>>,
+    pub crate_disambiguator: RefCell<Option<Fingerprint>>,
     pub features: RefCell<feature_gate::Features>,
 
     /// The maximum recursion limit for potentially infinitely recursive
@@ -165,7 +165,7 @@ enum DiagnosticBuilderMethod {
 }
 
 impl Session {
-    pub fn local_crate_disambiguator(&self) -> Symbol {
+    pub fn local_crate_disambiguator(&self) -> Fingerprint {
         match *self.crate_disambiguator.borrow() {
             Some(sym) => sym,
             None => bug!("accessing disambiguator before initialization"),
@@ -471,14 +471,17 @@ impl Session {
 
     /// Returns the symbol name for the registrar function,
     /// given the crate Svh and the function DefIndex.
-    pub fn generate_plugin_registrar_symbol(&self, disambiguator: Symbol, index: DefIndex)
+    pub fn generate_plugin_registrar_symbol(&self, disambiguator: Fingerprint,
+                                            index: DefIndex)
                                             -> String {
-        format!("__rustc_plugin_registrar__{}_{}", disambiguator, index.as_usize())
+        format!("__rustc_plugin_registrar__{}_{}", disambiguator.to_hex(),
+                                                   index.as_usize())
     }
 
-    pub fn generate_derive_registrar_symbol(&self, disambiguator: Symbol, index: DefIndex)
+    pub fn generate_derive_registrar_symbol(&self, disambiguator: Fingerprint, index: DefIndex)
                                             -> String {
-        format!("__rustc_derive_registrar__{}_{}", disambiguator, index.as_usize())
+        format!("__rustc_derive_registrar__{}_{}", disambiguator.to_hex(),
+                                                   index.as_usize())
     }
 
     pub fn sysroot<'a>(&'a self) -> &'a Path {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 3d5e8ea583ccc..51e924bd08b19 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1251,7 +1251,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 crate_name,
                 // Don't print the whole crate disambiguator. That's just
                 // annoying in debug output.
-                &(crate_disambiguator.as_str())[..4],
+                &(crate_disambiguator.to_hex())[..4],
                 self.def_path(def_id).to_string_no_crate())
     }
 
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 839042bf229aa..3c2630bb33a12 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -10,6 +10,7 @@
 
 use dep_graph::{DepConstructor, DepNode};
 use errors::DiagnosticBuilder;
+use ich::Fingerprint;
 use hir::def_id::{CrateNum, DefId, DefIndex};
 use hir::def::{Def, Export};
 use hir::{self, TraitCandidate, ItemLocalId};
@@ -283,7 +284,7 @@ define_maps! { <'tcx>
     [] fn native_libraries: NativeLibraries(CrateNum) -> Rc<Vec<NativeLibrary>>,
     [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
     [] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
-    [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> Symbol,
+    [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> Fingerprint,
     [] fn crate_hash: CrateHash(CrateNum) -> Svh,
     [] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol,
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 129c81c5cd61f..3b49cceee9010 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -19,7 +19,7 @@ use hir::{map as hir_map, FreevarMap, TraitMap};
 use hir::def::{Def, CtorKind, ExportMap};
 use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use hir::map::DefPathData;
-use ich::StableHashingContext;
+use ich::{Fingerprint, StableHashingContext};
 use middle::const_val::ConstVal;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use middle::privacy::AccessLevels;
@@ -2562,7 +2562,7 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn crate_disambiguator<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                 crate_num: CrateNum) -> Symbol {
+                                 crate_num: CrateNum) -> Fingerprint {
     assert_eq!(crate_num, LOCAL_CRATE);
     tcx.sess.local_crate_disambiguator()
 }
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 7dbf93da38598..6849cbbb062bb 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -58,7 +58,6 @@ use syntax::{ast, diagnostics, visit};
 use syntax::attr;
 use syntax::ext::base::ExtCtxt;
 use syntax::parse::{self, PResult};
-use syntax::symbol::Symbol;
 use syntax::util::node_count::NodeCounter;
 use syntax;
 use syntax_ext;
@@ -633,12 +632,12 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
 
     *sess.crate_types.borrow_mut() = collect_crate_types(sess, &krate.attrs);
 
-    let disambiguator = Symbol::intern(&compute_crate_disambiguator(sess));
+    let disambiguator = compute_crate_disambiguator(sess);
     *sess.crate_disambiguator.borrow_mut() = Some(disambiguator);
     rustc_incremental::prepare_session_directory(
         sess,
         &crate_name,
-        &disambiguator.as_str(),
+        &disambiguator,
     );
 
     let dep_graph = if sess.opts.build_dep_graph() {
@@ -1312,16 +1311,13 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
         .collect()
 }
 
-pub fn compute_crate_disambiguator(session: &Session) -> String {
+pub fn compute_crate_disambiguator(session: &Session) -> Fingerprint {
     use std::hash::Hasher;
 
     // The crate_disambiguator is a 128 bit hash. The disambiguator is fed
     // into various other hashes quite a bit (symbol hashes, incr. comp. hashes,
     // debuginfo type IDs, etc), so we don't want it to be too wide. 128 bits
     // should still be safe enough to avoid collisions in practice.
-    // FIXME(mw): It seems that the crate_disambiguator is used everywhere as
-    //            a hex-string instead of raw bytes. We should really use the
-    //            smaller representation.
     let mut hasher = StableHasher::<Fingerprint>::new();
 
     let mut metadata = session.opts.cg.metadata.clone();
@@ -1340,11 +1336,13 @@ pub fn compute_crate_disambiguator(session: &Session) -> String {
         hasher.write(s.as_bytes());
     }
 
-    // If this is an executable, add a special suffix, so that we don't get
-    // symbol conflicts when linking against a library of the same name.
+    // Also incorporate crate type, so that we don't get symbol conflicts when
+    // linking against a library of the same name, if this is an executable.
     let is_exe = session.crate_types.borrow().contains(&config::CrateTypeExecutable);
+    hasher.write(if is_exe { b"exe" } else { b"lib" });
+
+    hasher.finish()
 
-    format!("{}{}", hasher.finish().to_hex(), if is_exe { "-exe" } else {""})
 }
 
 pub fn build_output_filenames(input: &Input,
diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs
index d53ee5c804f60..bbca0aef600f4 100644
--- a/src/librustc_incremental/persist/fs.rs
+++ b/src/librustc_incremental/persist/fs.rs
@@ -114,6 +114,7 @@
 //! unsupported file system and emit a warning in that case. This is not yet
 //! implemented.
 
+use rustc::ich::Fingerprint;
 use rustc::hir::svh::Svh;
 use rustc::session::Session;
 use rustc::util::fs as fs_util;
@@ -188,7 +189,7 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu
 /// The garbage collection will take care of it.
 pub fn prepare_session_directory(sess: &Session,
                                  crate_name: &str,
-                                 crate_disambiguator: &str) {
+                                 crate_disambiguator: &Fingerprint) {
     if sess.opts.incremental.is_none() {
         return
     }
@@ -614,21 +615,15 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> {
 
 fn crate_path(sess: &Session,
               crate_name: &str,
-              crate_disambiguator: &str)
+              crate_disambiguator: &Fingerprint)
               -> PathBuf {
-    use std::hash::{Hasher, Hash};
-    use std::collections::hash_map::DefaultHasher;
 
     let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();
 
-    // The full crate disambiguator is really long. A hash of it should be
-    // sufficient.
-    let mut hasher = DefaultHasher::new();
-    crate_disambiguator.hash(&mut hasher);
-
+    let crate_disambiguator = crate_disambiguator.to_smaller_hash();
     let crate_name = format!("{}-{}",
                              crate_name,
-                             base_n::encode(hasher.finish(), INT_ENCODE_BASE));
+                             base_n::encode(crate_disambiguator, INT_ENCODE_BASE));
     incr_dir.join(crate_name)
 }
 
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 39bdf88925e44..475f0fac36ab7 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -15,6 +15,7 @@ use locator::{self, CratePaths};
 use native_libs::relevant_lib;
 use schema::CrateRoot;
 
+use rustc::ich::Fingerprint;
 use rustc::hir::def_id::{CrateNum, DefIndex, CRATE_DEF_INDEX};
 use rustc::hir::svh::Svh;
 use rustc::middle::allocator::AllocatorKind;
@@ -626,7 +627,7 @@ impl<'a> CrateLoader<'a> {
     pub fn find_plugin_registrar(&mut self,
                                  span: Span,
                                  name: &str)
-                                 -> Option<(PathBuf, Symbol, DefIndex)> {
+                                 -> Option<(PathBuf, Fingerprint, DefIndex)> {
         let ekrate = self.read_extension_crate(span, &ExternCrateInfo {
              name: Symbol::intern(name),
              ident: Symbol::intern(name),
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 9e47e96aee4ef..22af9d7c33a74 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -13,6 +13,7 @@
 
 use schema;
 
+use rustc::ich::Fingerprint;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex};
 use rustc::hir::map::definitions::DefPathTable;
 use rustc::hir::svh::Svh;
@@ -171,7 +172,7 @@ impl CrateMetadata {
     pub fn hash(&self) -> Svh {
         self.root.hash
     }
-    pub fn disambiguator(&self) -> Symbol {
+    pub fn disambiguator(&self) -> Fingerprint {
         self.root.disambiguator
     }
 
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 8eacc21ab003b..023ce209038e8 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -20,6 +20,7 @@ use rustc::middle::cstore::{CrateStore, DepKind,
                             LoadedMacro, EncodedMetadata,
                             EncodedMetadataHashes, NativeLibraryKind};
 use rustc::middle::stability::DeprecationEntry;
+use rustc::ich::Fingerprint;
 use rustc::hir::def;
 use rustc::session::Session;
 use rustc::ty::{self, TyCtxt};
@@ -384,7 +385,7 @@ impl CrateStore for cstore::CStore {
         self.get_crate_data(cnum).name
     }
 
-    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> Symbol
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> Fingerprint
     {
         self.get_crate_data(cnum).disambiguator()
     }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index dad0d26d2715d..baea919db663a 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -14,7 +14,7 @@ use index;
 use rustc::hir;
 use rustc::hir::def::{self, CtorKind};
 use rustc::hir::def_id::{DefIndex, DefId, CrateNum};
-use rustc::ich::StableHashingContext;
+use rustc::ich::{Fingerprint, StableHashingContext};
 use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary};
 use rustc::middle::lang_items;
 use rustc::mir;
@@ -191,7 +191,7 @@ pub struct CrateRoot {
     pub name: Symbol,
     pub triple: String,
     pub hash: hir::svh::Svh,
-    pub disambiguator: Symbol,
+    pub disambiguator: Fingerprint,
     pub panic_strategy: PanicStrategy,
     pub has_global_allocator: bool,
     pub has_default_lib_allocator: bool,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index c7ec1d072d085..4b8b9c57da7b0 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1417,7 +1417,7 @@ impl<'a> Resolver<'a> {
 
         let mut definitions = Definitions::new();
         DefCollector::new(&mut definitions, Mark::root())
-            .collect_root(crate_name, &session.local_crate_disambiguator().as_str());
+            .collect_root(crate_name, &session.local_crate_disambiguator().to_hex());
 
         let mut invocations = FxHashMap();
         invocations.insert(Mark::root(),
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index 4996972a64586..f518e5b8b8d61 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -34,7 +34,7 @@ pub fn threshold(tcx: TyCtxt) -> SymbolExportLevel {
 pub fn metadata_symbol_name(tcx: TyCtxt) -> String {
     format!("rust_metadata_{}_{}",
             tcx.crate_name(LOCAL_CRATE),
-            tcx.crate_disambiguator(LOCAL_CRATE))
+            tcx.crate_disambiguator(LOCAL_CRATE).to_hex())
 }
 
 fn crate_export_threshold(crate_type: config::CrateType) -> SymbolExportLevel {
diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs
index 0ebfe4daad18f..695950e672785 100644
--- a/src/librustc_trans/back/symbol_names.rs
+++ b/src/librustc_trans/back/symbol_names.rs
@@ -220,7 +220,7 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         if avoid_cross_crate_conflicts {
             hasher.hash(tcx.crate_name.as_str());
-            hasher.hash(tcx.sess.local_crate_disambiguator().as_str());
+            hasher.hash(tcx.sess.local_crate_disambiguator());
         }
     });
 

From 7fa64bcef3a23e2a19792ebe297ed17fab36c273 Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Tue, 24 Oct 2017 17:49:58 +0200
Subject: [PATCH 2/2] Introduce CrateDisambiguator newtype and fix tests

---
 src/librustc/hir/map/collector.rs        |  6 ++--
 src/librustc/hir/map/def_collector.rs    |  5 +++-
 src/librustc/hir/map/definitions.rs      |  7 +++--
 src/librustc/hir/map/mod.rs              |  2 +-
 src/librustc/middle/cstore.rs            |  6 ++--
 src/librustc/session/mod.rs              | 37 +++++++++++++++++++-----
 src/librustc/ty/context.rs               |  2 +-
 src/librustc/ty/maps/mod.rs              |  5 ++--
 src/librustc/ty/mod.rs                   |  5 ++--
 src/librustc_driver/driver.rs            |  8 ++---
 src/librustc_incremental/persist/fs.rs   | 17 ++++++-----
 src/librustc_metadata/creader.rs         |  5 ++--
 src/librustc_metadata/cstore.rs          |  4 +--
 src/librustc_metadata/cstore_impl.rs     |  5 ++--
 src/librustc_metadata/schema.rs          |  5 ++--
 src/librustc_resolve/lib.rs              |  2 +-
 src/librustc_trans/back/symbol_export.rs |  2 +-
 src/librustc_trans/base.rs               |  3 +-
 src/test/mir-opt/validate_1.rs           |  4 +--
 src/test/mir-opt/validate_4.rs           | 12 ++++----
 src/test/mir-opt/validate_5.rs           |  4 +--
 21 files changed, 87 insertions(+), 59 deletions(-)

diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 10900624d9283..816793cc1aaa0 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -11,8 +11,8 @@
 use super::*;
 
 use dep_graph::{DepGraph, DepKind, DepNodeIndex};
-use ich::Fingerprint;
 use hir::intravisit::{Visitor, NestedVisitorMap};
+use session::CrateDisambiguator;
 use std::iter::repeat;
 use syntax::ast::{NodeId, CRATE_NODE_ID};
 use syntax_pos::Span;
@@ -119,7 +119,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
     }
 
     pub(super) fn finalize_and_compute_crate_hash(self,
-                                                  crate_disambiguator: &Fingerprint)
+                                                  crate_disambiguator: CrateDisambiguator)
                                                   -> Vec<MapEntry<'hir>> {
         let mut node_hashes: Vec<_> = self
             .hir_body_nodes
@@ -134,7 +134,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
 
         self.dep_graph.with_task(DepNode::new_no_params(DepKind::Krate),
                                  &self.hcx,
-                                 (node_hashes, crate_disambiguator),
+                                 (node_hashes, crate_disambiguator.to_fingerprint()),
                                  identity_fn);
         self.map
     }
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index 673e6d3bbfbae..fcbe79131eb08 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -10,6 +10,7 @@
 
 use hir::map::definitions::*;
 use hir::def_id::{CRATE_DEF_INDEX, DefIndex, DefIndexAddressSpace};
+use session::CrateDisambiguator;
 
 use syntax::ast::*;
 use syntax::ext::hygiene::Mark;
@@ -43,7 +44,9 @@ impl<'a> DefCollector<'a> {
         }
     }
 
-    pub fn collect_root(&mut self, crate_name: &str, crate_disambiguator: &str) {
+    pub fn collect_root(&mut self,
+                        crate_name: &str,
+                        crate_disambiguator: CrateDisambiguator) {
         let root = self.definitions.create_root_def(crate_name,
                                                     crate_disambiguator);
         assert_eq!(root, CRATE_DEF_INDEX);
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index 8bc7cf2faba04..6418df479526c 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -22,6 +22,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::stable_hasher::StableHasher;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
+use session::CrateDisambiguator;
 use std::fmt::Write;
 use std::hash::Hash;
 use syntax::ast;
@@ -231,7 +232,9 @@ impl DefKey {
         DefPathHash(hasher.finish())
     }
 
-    fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> DefPathHash {
+    fn root_parent_stable_hash(crate_name: &str,
+                               crate_disambiguator: CrateDisambiguator)
+                               -> DefPathHash {
         let mut hasher = StableHasher::new();
         // Disambiguate this from a regular DefPath hash,
         // see compute_stable_hash() above.
@@ -467,7 +470,7 @@ impl Definitions {
     /// Add a definition with a parent definition.
     pub fn create_root_def(&mut self,
                            crate_name: &str,
-                           crate_disambiguator: &str)
+                           crate_disambiguator: CrateDisambiguator)
                            -> DefIndex {
         let key = DefKey {
             parent: None,
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 6da612fbaa684..a23658664dc6a 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -1015,7 +1015,7 @@ pub fn map_crate<'hir>(sess: &::session::Session,
         intravisit::walk_crate(&mut collector, &forest.krate);
 
         let crate_disambiguator = sess.local_crate_disambiguator();
-        collector.finalize_and_compute_crate_hash(&crate_disambiguator)
+        collector.finalize_and_compute_crate_hash(crate_disambiguator)
     };
 
     if log_enabled!(::log::LogLevel::Debug) {
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 39b2162bd328b..f4ba7890b170d 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -30,7 +30,7 @@ use hir::map::definitions::{Definitions, DefKey, DefPathTable};
 use hir::svh::Svh;
 use ich;
 use ty::{self, TyCtxt};
-use session::Session;
+use session::{Session, CrateDisambiguator};
 use session::search_paths::PathKind;
 use util::nodemap::NodeSet;
 
@@ -267,7 +267,7 @@ pub trait CrateStore {
     fn export_macros_untracked(&self, cnum: CrateNum);
     fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind;
     fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
-    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> ich::Fingerprint;
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator;
     fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
     fn struct_field_names_untracked(&self, def: DefId) -> Vec<ast::Name>;
     fn item_children_untracked(&self, did: DefId, sess: &Session) -> Vec<def::Export>;
@@ -338,7 +338,7 @@ impl CrateStore for DummyCrateStore {
     fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") }
     fn export_macros_untracked(&self, cnum: CrateNum) { bug!("export_macros") }
     fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol { bug!("crate_name") }
-    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> ich::Fingerprint {
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator {
         bug!("crate_disambiguator")
     }
     fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 23fea747f769e..c753a5309ce87 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -83,12 +83,12 @@ pub struct Session {
     pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
     pub crate_types: RefCell<Vec<config::CrateType>>,
     pub dependency_formats: RefCell<dependency_format::Dependencies>,
-    /// The crate_disambiguator is constructed out of all the `-C metadata`
+        /// The crate_disambiguator is constructed out of all the `-C metadata`
     /// arguments passed to the compiler. Its value together with the crate-name
     /// forms a unique global identifier for the crate. It is used to allow
     /// multiple crates with the same name to coexist. See the
     /// trans::back::symbol_names module for more information.
-    pub crate_disambiguator: RefCell<Option<Fingerprint>>,
+    pub crate_disambiguator: RefCell<Option<CrateDisambiguator>>,
     pub features: RefCell<feature_gate::Features>,
 
     /// The maximum recursion limit for potentially infinitely recursive
@@ -165,9 +165,9 @@ enum DiagnosticBuilderMethod {
 }
 
 impl Session {
-    pub fn local_crate_disambiguator(&self) -> Fingerprint {
+    pub fn local_crate_disambiguator(&self) -> CrateDisambiguator {
         match *self.crate_disambiguator.borrow() {
-            Some(sym) => sym,
+            Some(value) => value,
             None => bug!("accessing disambiguator before initialization"),
         }
     }
@@ -471,16 +471,17 @@ impl Session {
 
     /// Returns the symbol name for the registrar function,
     /// given the crate Svh and the function DefIndex.
-    pub fn generate_plugin_registrar_symbol(&self, disambiguator: Fingerprint,
+    pub fn generate_plugin_registrar_symbol(&self, disambiguator: CrateDisambiguator,
                                             index: DefIndex)
                                             -> String {
-        format!("__rustc_plugin_registrar__{}_{}", disambiguator.to_hex(),
+        format!("__rustc_plugin_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(),
                                                    index.as_usize())
     }
 
-    pub fn generate_derive_registrar_symbol(&self, disambiguator: Fingerprint, index: DefIndex)
+    pub fn generate_derive_registrar_symbol(&self, disambiguator: CrateDisambiguator,
+                                            index: DefIndex)
                                             -> String {
-        format!("__rustc_derive_registrar__{}_{}", disambiguator.to_hex(),
+        format!("__rustc_derive_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(),
                                                    index.as_usize())
     }
 
@@ -841,6 +842,26 @@ pub fn build_session_(sopts: config::Options,
     sess
 }
 
+/// Hash value constructed out of all the `-C metadata` arguments passed to the
+/// compiler. Together with the crate-name forms a unique global identifier for
+/// the crate.
+#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy, RustcEncodable, RustcDecodable)]
+pub struct CrateDisambiguator(Fingerprint);
+
+impl CrateDisambiguator {
+    pub fn to_fingerprint(self) -> Fingerprint {
+        self.0
+    }
+}
+
+impl From<Fingerprint> for CrateDisambiguator {
+    fn from(fingerprint: Fingerprint) -> CrateDisambiguator {
+        CrateDisambiguator(fingerprint)
+    }
+}
+
+impl_stable_hash_for!(tuple_struct CrateDisambiguator { fingerprint });
+
 /// Holds data on the current incremental compilation session, if there is one.
 #[derive(Debug)]
 pub enum IncrCompSession {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 51e924bd08b19..5f9cd0cb8b1fd 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1251,7 +1251,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 crate_name,
                 // Don't print the whole crate disambiguator. That's just
                 // annoying in debug output.
-                &(crate_disambiguator.to_hex())[..4],
+                &(crate_disambiguator.to_fingerprint().to_hex())[..4],
                 self.def_path(def_id).to_string_no_crate())
     }
 
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 3c2630bb33a12..a1a946a5d794d 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -10,7 +10,6 @@
 
 use dep_graph::{DepConstructor, DepNode};
 use errors::DiagnosticBuilder;
-use ich::Fingerprint;
 use hir::def_id::{CrateNum, DefId, DefIndex};
 use hir::def::{Def, Export};
 use hir::{self, TraitCandidate, ItemLocalId};
@@ -30,7 +29,7 @@ use middle::lang_items::{LanguageItems, LangItem};
 use middle::exported_symbols::SymbolExportLevel;
 use middle::trans::{CodegenUnit, Stats};
 use mir;
-use session::CompileResult;
+use session::{CompileResult, CrateDisambiguator};
 use session::config::OutputFilenames;
 use traits::Vtable;
 use traits::specialization_graph;
@@ -284,7 +283,7 @@ define_maps! { <'tcx>
     [] fn native_libraries: NativeLibraries(CrateNum) -> Rc<Vec<NativeLibrary>>,
     [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option<DefId>,
     [] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option<DefId>,
-    [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> Fingerprint,
+    [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator,
     [] fn crate_hash: CrateHash(CrateNum) -> Svh,
     [] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol,
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 3b49cceee9010..e15c3c9c453c8 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -19,13 +19,14 @@ use hir::{map as hir_map, FreevarMap, TraitMap};
 use hir::def::{Def, CtorKind, ExportMap};
 use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use hir::map::DefPathData;
-use ich::{Fingerprint, StableHashingContext};
+use ich::StableHashingContext;
 use middle::const_val::ConstVal;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use middle::privacy::AccessLevels;
 use middle::resolve_lifetime::ObjectLifetimeDefault;
 use mir::Mir;
 use mir::GeneratorLayout;
+use session::CrateDisambiguator;
 use traits;
 use ty;
 use ty::subst::{Subst, Substs};
@@ -2562,7 +2563,7 @@ fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn crate_disambiguator<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                 crate_num: CrateNum) -> Fingerprint {
+                                 crate_num: CrateNum) -> CrateDisambiguator {
     assert_eq!(crate_num, LOCAL_CRATE);
     tcx.sess.local_crate_disambiguator()
 }
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 6849cbbb062bb..cd3740f72e0f4 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -14,7 +14,7 @@ use rustc::hir::lowering::lower_crate;
 use rustc::ich::Fingerprint;
 use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_mir as mir;
-use rustc::session::{Session, CompileResult};
+use rustc::session::{Session, CompileResult, CrateDisambiguator};
 use rustc::session::CompileIncomplete;
 use rustc::session::config::{self, Input, OutputFilenames, OutputType};
 use rustc::session::search_paths::PathKind;
@@ -637,7 +637,7 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
     rustc_incremental::prepare_session_directory(
         sess,
         &crate_name,
-        &disambiguator,
+        disambiguator,
     );
 
     let dep_graph = if sess.opts.build_dep_graph() {
@@ -1311,7 +1311,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
         .collect()
 }
 
-pub fn compute_crate_disambiguator(session: &Session) -> Fingerprint {
+pub fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator {
     use std::hash::Hasher;
 
     // The crate_disambiguator is a 128 bit hash. The disambiguator is fed
@@ -1341,7 +1341,7 @@ pub fn compute_crate_disambiguator(session: &Session) -> Fingerprint {
     let is_exe = session.crate_types.borrow().contains(&config::CrateTypeExecutable);
     hasher.write(if is_exe { b"exe" } else { b"lib" });
 
-    hasher.finish()
+    CrateDisambiguator::from(hasher.finish())
 
 }
 
diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs
index bbca0aef600f4..89310b9d6f589 100644
--- a/src/librustc_incremental/persist/fs.rs
+++ b/src/librustc_incremental/persist/fs.rs
@@ -114,9 +114,8 @@
 //! unsupported file system and emit a warning in that case. This is not yet
 //! implemented.
 
-use rustc::ich::Fingerprint;
 use rustc::hir::svh::Svh;
-use rustc::session::Session;
+use rustc::session::{Session, CrateDisambiguator};
 use rustc::util::fs as fs_util;
 use rustc_data_structures::{flock, base_n};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
@@ -189,7 +188,7 @@ pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBu
 /// The garbage collection will take care of it.
 pub fn prepare_session_directory(sess: &Session,
                                  crate_name: &str,
-                                 crate_disambiguator: &Fingerprint) {
+                                 crate_disambiguator: CrateDisambiguator) {
     if sess.opts.incremental.is_none() {
         return
     }
@@ -615,15 +614,17 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> {
 
 fn crate_path(sess: &Session,
               crate_name: &str,
-              crate_disambiguator: &Fingerprint)
+              crate_disambiguator: CrateDisambiguator)
               -> PathBuf {
 
     let incr_dir = sess.opts.incremental.as_ref().unwrap().clone();
 
-    let crate_disambiguator = crate_disambiguator.to_smaller_hash();
-    let crate_name = format!("{}-{}",
-                             crate_name,
-                             base_n::encode(crate_disambiguator, INT_ENCODE_BASE));
+    // The full crate disambiguator is really long. 64 bits of it should be
+    // sufficient.
+    let crate_disambiguator = crate_disambiguator.to_fingerprint().to_smaller_hash();
+    let crate_disambiguator = base_n::encode(crate_disambiguator, INT_ENCODE_BASE);
+
+    let crate_name = format!("{}-{}", crate_name, crate_disambiguator);
     incr_dir.join(crate_name)
 }
 
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 475f0fac36ab7..cfc8d271327fb 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -15,12 +15,11 @@ use locator::{self, CratePaths};
 use native_libs::relevant_lib;
 use schema::CrateRoot;
 
-use rustc::ich::Fingerprint;
 use rustc::hir::def_id::{CrateNum, DefIndex, CRATE_DEF_INDEX};
 use rustc::hir::svh::Svh;
 use rustc::middle::allocator::AllocatorKind;
 use rustc::middle::cstore::DepKind;
-use rustc::session::Session;
+use rustc::session::{Session, CrateDisambiguator};
 use rustc::session::config::{Sanitizer, self};
 use rustc_back::PanicStrategy;
 use rustc::session::search_paths::PathKind;
@@ -627,7 +626,7 @@ impl<'a> CrateLoader<'a> {
     pub fn find_plugin_registrar(&mut self,
                                  span: Span,
                                  name: &str)
-                                 -> Option<(PathBuf, Fingerprint, DefIndex)> {
+                                 -> Option<(PathBuf, CrateDisambiguator, DefIndex)> {
         let ekrate = self.read_extension_crate(span, &ExternCrateInfo {
              name: Symbol::intern(name),
              ident: Symbol::intern(name),
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 22af9d7c33a74..c688b4c408a35 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -13,11 +13,11 @@
 
 use schema;
 
-use rustc::ich::Fingerprint;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex};
 use rustc::hir::map::definitions::DefPathTable;
 use rustc::hir::svh::Svh;
 use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
+use rustc::session::CrateDisambiguator;
 use rustc_back::PanicStrategy;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
@@ -172,7 +172,7 @@ impl CrateMetadata {
     pub fn hash(&self) -> Svh {
         self.root.hash
     }
-    pub fn disambiguator(&self) -> Fingerprint {
+    pub fn disambiguator(&self) -> CrateDisambiguator {
         self.root.disambiguator
     }
 
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 023ce209038e8..fbe63e0ab4a8a 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -20,9 +20,8 @@ use rustc::middle::cstore::{CrateStore, DepKind,
                             LoadedMacro, EncodedMetadata,
                             EncodedMetadataHashes, NativeLibraryKind};
 use rustc::middle::stability::DeprecationEntry;
-use rustc::ich::Fingerprint;
 use rustc::hir::def;
-use rustc::session::Session;
+use rustc::session::{CrateDisambiguator, Session};
 use rustc::ty::{self, TyCtxt};
 use rustc::ty::maps::Providers;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
@@ -385,7 +384,7 @@ impl CrateStore for cstore::CStore {
         self.get_crate_data(cnum).name
     }
 
-    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> Fingerprint
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator
     {
         self.get_crate_data(cnum).disambiguator()
     }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index baea919db663a..43dbce5288a7e 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -14,10 +14,11 @@ use index;
 use rustc::hir;
 use rustc::hir::def::{self, CtorKind};
 use rustc::hir::def_id::{DefIndex, DefId, CrateNum};
-use rustc::ich::{Fingerprint, StableHashingContext};
+use rustc::ich::StableHashingContext;
 use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary};
 use rustc::middle::lang_items;
 use rustc::mir;
+use rustc::session::CrateDisambiguator;
 use rustc::ty::{self, Ty, ReprOptions};
 use rustc_back::PanicStrategy;
 
@@ -191,7 +192,7 @@ pub struct CrateRoot {
     pub name: Symbol,
     pub triple: String,
     pub hash: hir::svh::Svh,
-    pub disambiguator: Fingerprint,
+    pub disambiguator: CrateDisambiguator,
     pub panic_strategy: PanicStrategy,
     pub has_global_allocator: bool,
     pub has_default_lib_allocator: bool,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 4b8b9c57da7b0..2b6eaf12f1bce 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1417,7 +1417,7 @@ impl<'a> Resolver<'a> {
 
         let mut definitions = Definitions::new();
         DefCollector::new(&mut definitions, Mark::root())
-            .collect_root(crate_name, &session.local_crate_disambiguator().to_hex());
+            .collect_root(crate_name, session.local_crate_disambiguator());
 
         let mut invocations = FxHashMap();
         invocations.insert(Mark::root(),
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index f518e5b8b8d61..eb1c5cb788153 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -34,7 +34,7 @@ pub fn threshold(tcx: TyCtxt) -> SymbolExportLevel {
 pub fn metadata_symbol_name(tcx: TyCtxt) -> String {
     format!("rust_metadata_{}_{}",
             tcx.crate_name(LOCAL_CRATE),
-            tcx.crate_disambiguator(LOCAL_CRATE).to_hex())
+            tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex())
 }
 
 fn crate_export_threshold(crate_type: config::CrateType) -> SymbolExportLevel {
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 547b1f7b2bf96..5ad3a7d26558a 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -1312,7 +1312,8 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // 1. http://llvm.org/bugs/show_bug.cgi?id=11479
         let llmod_id = format!("{}-{}.rs",
                                cgu.name(),
-                               tcx.crate_disambiguator(LOCAL_CRATE));
+                               tcx.crate_disambiguator(LOCAL_CRATE)
+                                   .to_fingerprint().to_hex());
 
         // Instantiate translation items without filling out definitions yet...
         let scx = SharedCrateContext::new(tcx);
diff --git a/src/test/mir-opt/validate_1.rs b/src/test/mir-opt/validate_1.rs
index 22788d7a8985e..aa97fc10e720b 100644
--- a/src/test/mir-opt/validate_1.rs
+++ b/src/test/mir-opt/validate_1.rs
@@ -30,7 +30,7 @@ fn main() {
 // END RUST SOURCE
 // START rustc.node12.EraseRegions.after.mir
 //     bb0: {
-//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:5) => validate_1[e36f]::{{impl}}[0]::foo[0] }, BrAnon(0)) Test, _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:5) => validate_1[e36f]::{{impl}}[0]::foo[0] }, BrAnon(1)) mut i32]);
+//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:5) => validate_1[317d]::{{impl}}[0]::foo[0] }, BrAnon(0)) Test, _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:5) => validate_1[317d]::{{impl}}[0]::foo[0] }, BrAnon(1)) mut i32]);
 //         ...
 //         return;
 //     }
@@ -62,7 +62,7 @@ fn main() {
 // fn main::{{closure}}(_1: &ReErased [closure@NodeId(50)], _2: &ReErased mut i32) -> i32 {
 //     ...
 //     bb0: {
-//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[e36f]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(50)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[e36f]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
+//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[317d]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(50)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:11) => validate_1[317d]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
 //         StorageLive(_3);
 //         _3 = _2;
 //         StorageLive(_4);
diff --git a/src/test/mir-opt/validate_4.rs b/src/test/mir-opt/validate_4.rs
index d2852cf522618..dec181f62dc49 100644
--- a/src/test/mir-opt/validate_4.rs
+++ b/src/test/mir-opt/validate_4.rs
@@ -51,8 +51,8 @@ fn main() {
 // fn write_42::{{closure}}(_1: &ReErased [closure@NodeId(22)], _2: *mut i32) -> () {
 //     ...
 //     bb0: {
-//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[e36f]::write_42[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(22)], _2: *mut i32]);
-//         Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[e36f]::write_42[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(22)], _2: *mut i32]);
+//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[317d]::write_42[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(22)], _2: *mut i32]);
+//         Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_4[317d]::write_42[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(22)], _2: *mut i32]);
 //         StorageLive(_3);
 //         _3 = _2;
 //         (*_3) = const 23i32;
@@ -65,8 +65,8 @@ fn main() {
 // fn test(_1: &ReErased mut i32) -> () {
 //     ...
 //     bb0: {
-//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:4) => validate_4[e36f]::test[0] }, BrAnon(0)) mut i32]);
-//         Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:4) => validate_4[e36f]::test[0] }, BrAnon(0)) mut i32]);
+//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:4) => validate_4[317d]::test[0] }, BrAnon(0)) mut i32]);
+//         Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:4) => validate_4[317d]::test[0] }, BrAnon(0)) mut i32]);
 //         ...
 //         _3 = const write_42(_4) -> bb1;
 //     }
@@ -81,8 +81,8 @@ fn main() {
 // fn main::{{closure}}(_1: &ReErased [closure@NodeId(60)], _2: &ReErased mut i32) -> bool {
 //     ...
 //     bb0: {
-//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[e36f]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[e36f]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
-//         Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[e36f]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[e36f]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
+//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[317d]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[317d]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
+//         Validate(Release, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[317d]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:10) => validate_4[317d]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
 //         StorageLive(_3);
 //         ...
 //         _0 = const write_42(_4) -> bb1;
diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs
index 98c553d6b35af..47a6942b830e2 100644
--- a/src/test/mir-opt/validate_5.rs
+++ b/src/test/mir-opt/validate_5.rs
@@ -37,7 +37,7 @@ fn main() {
 // fn test(_1: &ReErased mut i32) -> () {
 //     ...
 //     bb0: {
-//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:4) => validate_5[e36f]::test[0] }, BrAnon(0)) mut i32]);
+//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(0:4) => validate_5[317d]::test[0] }, BrAnon(0)) mut i32]);
 //         ...
 //         Validate(Release, [_3: bool, _4: *mut i32]);
 //         _3 = const write_42(_4) -> bb1;
@@ -49,7 +49,7 @@ fn main() {
 // fn main::{{closure}}(_1: &ReErased [closure@NodeId(46)], _2: &ReErased mut i32) -> bool {
 //     ...
 //     bb0: {
-//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[e36f]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(46)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[e36f]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
+//         Validate(Acquire, [_1: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[317d]::main[0]::{{closure}}[0] }, BrEnv) [closure@NodeId(46)], _2: &ReFree(DefId { krate: CrateNum(0), index: DefIndex(1:9) => validate_5[317d]::main[0]::{{closure}}[0] }, BrAnon(1)) mut i32]);
 //         StorageLive(_3);
 //         _3 = _2;
 //         StorageLive(_4);