diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 91bce64243e3f..cdd5a6e3da7f1 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -18,7 +18,7 @@ use hir; use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace, CRATE_DEF_INDEX}; use ich::Fingerprint; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +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}; @@ -153,7 +153,7 @@ pub struct Definitions { pub(super) node_to_hir_id: IndexVec, macro_def_scopes: FxHashMap, expansions: FxHashMap, - keys_created: FxHashSet, + next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>, } // Unfortunately we have to provide a manual impl of Clone because of the @@ -170,7 +170,7 @@ impl Clone for Definitions { node_to_hir_id: self.node_to_hir_id.clone(), macro_def_scopes: self.macro_def_scopes.clone(), expansions: self.expansions.clone(), - keys_created: self.keys_created.clone(), + next_disambiguator: self.next_disambiguator.clone(), } } } @@ -402,7 +402,7 @@ impl Definitions { node_to_hir_id: IndexVec::new(), macro_def_scopes: FxHashMap(), expansions: FxHashMap(), - keys_created: FxHashSet(), + next_disambiguator: FxHashMap(), } } @@ -516,21 +516,21 @@ impl Definitions { // The root node must be created with create_root_def() assert!(data != DefPathData::CrateRoot); - // Find a unique DefKey. This basically means incrementing the disambiguator - // until we get no match. - let mut key = DefKey { + // Find the next free disambiguator for this key. + let disambiguator = { + let next_disamb = self.next_disambiguator.entry((parent, data.clone())).or_insert(0); + let disambiguator = *next_disamb; + *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow"); + disambiguator + }; + + let key = DefKey { parent: Some(parent), disambiguated_data: DisambiguatedDefPathData { - data, - disambiguator: 0 + data, disambiguator } }; - while self.keys_created.contains(&key) { - key.disambiguated_data.disambiguator += 1; - } - self.keys_created.insert(key.clone()); - let parent_hash = self.table.def_path_hash(parent); let def_path_hash = key.compute_stable_hash(parent_hash); diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index b3d9cf9da36c7..bfdcae7641dd5 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -561,8 +561,9 @@ impl CodeMapper for CodeMap { sp } fn ensure_filemap_source_present(&self, file_map: Rc) -> bool { - let src = self.file_loader.read_file(Path::new(&file_map.name)).ok(); - return file_map.add_external_src(src) + file_map.add_external_src( + || self.file_loader.read_file(Path::new(&file_map.name)).ok() + ) } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 3a701f91314b6..7006f45455e38 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -618,8 +618,11 @@ impl FileMap { /// If the hash of the input doesn't match or no input is supplied via None, /// it is interpreted as an error and the corresponding enum variant is set. /// The return value signifies whether some kind of source is present. - pub fn add_external_src(&self, src: Option) -> bool { + pub fn add_external_src(&self, get_src: F) -> bool + where F: FnOnce() -> Option + { if *self.external_src.borrow() == ExternalSource::AbsentOk { + let src = get_src(); let mut external_src = self.external_src.borrow_mut(); if let Some(src) = src { let mut hasher: StableHasher = StableHasher::new();