@@ -8,6 +8,7 @@ use std::fmt::{self, Write};
88use std:: hash:: Hash ;
99
1010use rustc_data_structures:: fx:: FxHashMap ;
11+ use rustc_data_structures:: indexmap:: IndexSet ;
1112use rustc_data_structures:: stable_hash:: StableHasher ;
1213use rustc_hashes:: Hash64 ;
1314use rustc_index:: IndexVec ;
@@ -52,6 +53,7 @@ pub struct Definitions {
5253 // We do only store the local hash, as all the definitions are from the current crate.
5354 def_path_hashes : IndexVec < LocalDefId , Hash64 > ,
5455 def_path_hash_to_index : DefPathHashMap ,
56+ allow_overwrite : IndexSet < LocalDefId > ,
5557}
5658
5759/// A unique identifier that we can use to lookup a definition
@@ -298,46 +300,60 @@ impl Definitions {
298300 def_path_hashes : Default :: default ( ) ,
299301 def_id_to_key : Default :: default ( ) ,
300302 def_path_hash_to_index : Default :: default ( ) ,
303+ allow_overwrite : Default :: default ( ) ,
301304 } ;
302305
303306 // Create the root definition.
304- let root = defs. allocate ( key, def_path_hash) ;
307+ let root = defs. allocate ( key, def_path_hash, false ) ;
305308 assert_eq ! ( root. local_def_index, CRATE_DEF_INDEX ) ;
306309
307310 defs
308311 }
309312
310- fn allocate ( & mut self , key : DefKey , def_path_hash : DefPathHash ) -> LocalDefId {
313+ fn allocate (
314+ & mut self ,
315+ key : DefKey ,
316+ def_path_hash : DefPathHash ,
317+ in_sandbox : bool ,
318+ ) -> LocalDefId {
311319 // Assert that all DefPathHashes correctly contain the local crate's StableCrateId.
312320 debug_assert_eq ! ( self . stable_crate_id, def_path_hash. stable_crate_id( ) ) ;
313321 let local_hash = def_path_hash. local_hash ( ) ;
314-
315- let def_id = self . def_id_to_key . push ( key) ;
316- debug ! ( "def_id_to_key.push() - {key:?} <-> {:?}" , def_id. local_def_index) ;
317-
318- self . def_path_hashes . push ( local_hash) ;
319- debug_assert ! ( self . def_path_hashes. len( ) == self . def_id_to_key. len( ) ) ;
322+ let def_id = self . def_id_to_key . next_index ( ) ;
320323
321324 // Check for hash collisions of DefPathHashes. These should be
322325 // exceedingly rare.
323326 if let Some ( existing) =
324327 self . def_path_hash_to_index . insert ( & local_hash, & def_id. local_def_index )
325328 {
326- let def_path1 = self . def_path ( LocalDefId { local_def_index : existing } ) ;
327- let def_path2 = self . def_path ( def_id) ;
328-
329- // Continuing with colliding DefPathHashes can lead to correctness
330- // issues. We must abort compilation.
331- //
332- // The likelihood of such a collision is very small, so actually
333- // running into one could be indicative of a poor hash function
334- // being used.
335- //
336- // See the documentation for DefPathHash for more information.
337- panic ! (
338- "found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
329+ let existing = LocalDefId { local_def_index : existing } ;
330+
331+ if !in_sandbox && self . allow_overwrite . swap_remove ( & existing) {
332+ self . def_path_hash_to_index . insert ( & local_hash, & existing. local_def_index ) ;
333+ return existing;
334+ } else {
335+ let def_path1 = self . def_path ( existing) ;
336+ let def_path2 = self . def_path ( def_id) ;
337+
338+ // Continuing with colliding DefPathHashes can lead to correctness
339+ // issues. We must abort compilation.
340+ //
341+ // The likelihood of such a collision is very small, so actually
342+ // running into one could be indicative of a poor hash function
343+ // being used.
344+ //
345+ // See the documentation for DefPathHash for more information.
346+ panic ! (
347+ "found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
339348 Compilation cannot continue."
340- ) ;
349+ ) ;
350+ }
351+ } else {
352+ self . def_id_to_key . push ( key) ;
353+ debug ! ( "def_id_to_key.push() - {key:?} <-> {:?}" , def_id. local_def_index) ;
354+
355+ self . def_path_hashes . push ( local_hash) ;
356+ debug_assert ! ( self . def_path_hashes. len( ) == self . def_id_to_key. len( ) ) ;
341357 }
342358
343359 def_id
@@ -361,6 +377,7 @@ impl Definitions {
361377 parent : LocalDefId ,
362378 data : DefPathData ,
363379 disambiguator : & mut PerParentDisambiguatorState ,
380+ in_sandbox : bool ,
364381 ) -> LocalDefId {
365382 // We can't use `Debug` implementation for `LocalDefId` here, since it tries to acquire a
366383 // reference to `Definitions` and we're already holding a mutable reference.
@@ -396,8 +413,12 @@ impl Definitions {
396413
397414 debug ! ( "create_def: after disambiguation, key = {:?}" , key) ;
398415
399- // Create the definition.
400- self . allocate ( key, def_path_hash)
416+ let def_id = self . allocate ( key, def_path_hash, in_sandbox) ;
417+ if in_sandbox {
418+ assert_eq ! ( self . allow_overwrite. insert( def_id) , true ) ;
419+ }
420+
421+ def_id
401422 }
402423
403424 #[ inline( always) ]
0 commit comments