77use std:: fmt:: { self , Write } ;
88use std:: hash:: Hash ;
99
10+ use rustc_data_structures:: indexmap:: IndexSet ;
1011use rustc_data_structures:: stable_hasher:: StableHasher ;
1112use rustc_data_structures:: unord:: UnordMap ;
1213use rustc_hashes:: Hash64 ;
@@ -30,6 +31,7 @@ pub struct DefPathTable {
3031 // We do only store the local hash, as all the definitions are from the current crate.
3132 def_path_hashes : IndexVec < DefIndex , Hash64 > ,
3233 def_path_hash_to_index : DefPathHashMap ,
34+ allow_overwrite : IndexSet < DefIndex > ,
3335}
3436
3537impl DefPathTable {
@@ -39,38 +41,45 @@ impl DefPathTable {
3941 index_to_key : Default :: default ( ) ,
4042 def_path_hashes : Default :: default ( ) ,
4143 def_path_hash_to_index : Default :: default ( ) ,
44+ allow_overwrite : Default :: default ( ) ,
4245 }
4346 }
4447
45- fn allocate ( & mut self , key : DefKey , def_path_hash : DefPathHash ) -> DefIndex {
48+ fn allocate ( & mut self , key : DefKey , def_path_hash : DefPathHash , in_sandbox : bool ) -> DefIndex {
4649 // Assert that all DefPathHashes correctly contain the local crate's StableCrateId.
4750 debug_assert_eq ! ( self . stable_crate_id, def_path_hash. stable_crate_id( ) ) ;
4851 let local_hash = def_path_hash. local_hash ( ) ;
49-
50- let index = self . index_to_key . push ( key) ;
51- debug ! ( "DefPathTable::insert() - {key:?} <-> {index:?}" ) ;
52-
53- self . def_path_hashes . push ( local_hash) ;
54- debug_assert ! ( self . def_path_hashes. len( ) == self . index_to_key. len( ) ) ;
52+ let index = self . index_to_key . next_index ( ) ;
5553
5654 // Check for hash collisions of DefPathHashes. These should be
5755 // exceedingly rare.
5856 if let Some ( existing) = self . def_path_hash_to_index . insert ( & local_hash, & index) {
59- let def_path1 = DefPath :: make ( LOCAL_CRATE , existing, |idx| self . def_key ( idx) ) ;
60- let def_path2 = DefPath :: make ( LOCAL_CRATE , index, |idx| self . def_key ( idx) ) ;
61-
62- // Continuing with colliding DefPathHashes can lead to correctness
63- // issues. We must abort compilation.
64- //
65- // The likelihood of such a collision is very small, so actually
66- // running into one could be indicative of a poor hash function
67- // being used.
68- //
69- // See the documentation for DefPathHash for more information.
70- panic ! (
71- "found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
57+ if !in_sandbox && self . allow_overwrite . swap_remove ( & existing) {
58+ self . def_path_hash_to_index . insert ( & local_hash, & existing) ;
59+ return existing;
60+ } else {
61+ let def_path1 = DefPath :: make ( LOCAL_CRATE , existing, |idx| self . def_key ( idx) ) ;
62+ let def_path2 = DefPath :: make ( LOCAL_CRATE , index, |idx| self . def_key ( idx) ) ;
63+
64+ // Continuing with colliding DefPathHashes can lead to correctness
65+ // issues. We must abort compilation.
66+ //
67+ // The likelihood of such a collision is very small, so actually
68+ // running into one could be indicative of a poor hash function
69+ // being used.
70+ //
71+ // See the documentation for DefPathHash for more information.
72+ panic ! (
73+ "found DefPathHash collision between {def_path1:#?} and {def_path2:#?}. \
7274 Compilation cannot continue."
73- ) ;
75+ ) ;
76+ }
77+ } else {
78+ self . index_to_key . push ( key) ;
79+ debug ! ( "DefPathTable::insert() - {key:?} <-> {index:?}" ) ;
80+
81+ self . def_path_hashes . push ( local_hash) ;
82+ debug_assert ! ( self . def_path_hashes. len( ) == self . index_to_key. len( ) ) ;
7483 }
7584
7685 index
@@ -374,7 +383,7 @@ impl Definitions {
374383
375384 // Create the root definition.
376385 let mut table = DefPathTable :: new ( stable_crate_id) ;
377- let root = LocalDefId { local_def_index : table. allocate ( key, def_path_hash) } ;
386+ let root = LocalDefId { local_def_index : table. allocate ( key, def_path_hash, false ) } ;
378387 assert_eq ! ( root. local_def_index, CRATE_DEF_INDEX ) ;
379388
380389 Definitions { table }
@@ -390,6 +399,7 @@ impl Definitions {
390399 parent : LocalDefId ,
391400 data : DefPathData ,
392401 disambiguator : & mut DisambiguatorState ,
402+ in_sandbox : bool ,
393403 ) -> LocalDefId {
394404 // We can't use `Debug` implementation for `LocalDefId` here, since it tries to acquire a
395405 // reference to `Definitions` and we're already holding a mutable reference.
@@ -418,8 +428,14 @@ impl Definitions {
418428
419429 debug ! ( "create_def: after disambiguation, key = {:?}" , key) ;
420430
431+ let local_def_index = self . table . allocate ( key, def_path_hash, in_sandbox) ;
432+
433+ if in_sandbox {
434+ assert_eq ! ( self . table. allow_overwrite. insert( local_def_index) , true ) ;
435+ }
436+
421437 // Create the definition.
422- LocalDefId { local_def_index : self . table . allocate ( key , def_path_hash ) }
438+ LocalDefId { local_def_index }
423439 }
424440
425441 #[ inline( always) ]
0 commit comments