@@ -766,8 +766,13 @@ impl Clone for ReplaceSource {
766766impl Hash for ReplaceSource {
767767 fn hash < H : Hasher > ( & self , state : & mut H ) {
768768 "ReplaceSource" . hash ( state) ;
769+ // replacements are ordered, so when hashing,
770+ // skip fields (enforce and insertion_order) that are only used
769771 for repl in & self . replacements {
770- repl. hash ( state) ;
772+ repl. start . hash ( state) ;
773+ repl. end . hash ( state) ;
774+ repl. content . hash ( state) ;
775+ repl. name . hash ( state) ;
771776 }
772777 self . inner . hash ( state) ;
773778 }
@@ -784,6 +789,8 @@ impl Eq for ReplaceSource {}
784789
785790#[ cfg( test) ]
786791mod tests {
792+ use rustc_hash:: FxHasher ;
793+
787794 use crate :: {
788795 source_map_source:: WithoutOriginalOptions , OriginalSource , RawStringSource ,
789796 ReplacementEnforce , SourceExt , SourceMapSource ,
@@ -1185,7 +1192,7 @@ return <div>{data.foo}</div>
11851192 assert_eq ! ( source. map( & MapOptions :: default ( ) ) , None ) ;
11861193 let mut hasher = twox_hash:: XxHash64 :: default ( ) ;
11871194 source. hash ( & mut hasher) ;
1188- assert_eq ! ( format!( "{:x}" , hasher. finish( ) ) , "15e48cdf294935ab " ) ;
1195+ assert_eq ! ( format!( "{:x}" , hasher. finish( ) ) , "96abdb94c6fd5aba " ) ;
11891196 }
11901197
11911198 #[ test]
@@ -1360,4 +1367,25 @@ return <div>{data.foo}</div>
13601367
13611368 assert_eq ! ( source. size( ) , source. source( ) . into_string_lossy( ) . len( ) ) ;
13621369 }
1370+
1371+ #[ test]
1372+ fn replace_source_hash_is_order_independent ( ) {
1373+ let mut source1 =
1374+ ReplaceSource :: new ( RawStringSource :: from_static ( "hello, world!" ) . boxed ( ) ) ;
1375+ source1. replace ( 0 , 5 , "你好" , None ) ;
1376+ source1. replace ( 6 , 11 , "世界" , None ) ;
1377+
1378+ let mut source2 =
1379+ ReplaceSource :: new ( RawStringSource :: from_static ( "hello, world!" ) . boxed ( ) ) ;
1380+ source2. replace ( 6 , 11 , "世界" , None ) ;
1381+ source2. replace ( 0 , 5 , "你好" , None ) ;
1382+
1383+ assert_eq ! ( source1. source( ) , source2. source( ) ) ;
1384+
1385+ let mut hasher1 = FxHasher :: default ( ) ;
1386+ source1. hash ( & mut hasher1) ;
1387+ let mut hasher2 = FxHasher :: default ( ) ;
1388+ source2. hash ( & mut hasher2) ;
1389+ assert_eq ! ( hasher1. finish( ) , hasher2. finish( ) ) ;
1390+ }
13631391}
0 commit comments