@@ -6,9 +6,8 @@ use std::env;
6
6
use std:: fmt;
7
7
use std:: hash:: { Hash , Hasher } ;
8
8
use std:: iter:: FromIterator ;
9
- use std:: sync:: atomic:: AtomicBool ;
10
- use std:: sync:: atomic:: AtomicUsize ;
11
- use std:: sync:: atomic:: Ordering :: SeqCst ;
9
+ use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
10
+ use std:: sync:: Once ;
12
11
13
12
use crate :: ast;
14
13
use proc_macro2:: { self , Ident } ;
@@ -133,13 +132,13 @@ pub fn wrap_import_function(function: ast::ImportFunction) -> ast::Import {
133
132
pub struct ShortHash < T > ( pub T ) ;
134
133
135
134
impl < T : Hash > fmt:: Display for ShortHash < T > {
136
- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
137
- static HASHED : AtomicBool = AtomicBool :: new ( false ) ;
138
- static HASH : AtomicUsize = AtomicUsize :: new ( 0 ) ;
135
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
136
+ static INIT : Once = Once :: new ( ) ;
137
+ static HASH_SEED : AtomicUsize = AtomicUsize :: new ( 0 ) ;
139
138
140
139
// Try to amortize the cost of loading env vars a lot as we're gonna be
141
140
// hashing for a lot of symbols.
142
- if ! HASHED . load ( SeqCst ) {
141
+ INIT . call_once ( || {
143
142
let mut h = DefaultHasher :: new ( ) ;
144
143
env:: var ( "CARGO_PKG_NAME" )
145
144
. expect ( "should have CARGO_PKG_NAME env var" )
@@ -149,13 +148,26 @@ impl<T: Hash> fmt::Display for ShortHash<T> {
149
148
. hash ( & mut h) ;
150
149
// This may chop off 32 bits on 32-bit platforms, but that's ok, we
151
150
// just want something to mix in below anyway.
152
- HASH . store ( h. finish ( ) as usize , SeqCst ) ;
153
- HASHED . store ( true , SeqCst ) ;
154
- }
151
+ HASH_SEED . store ( h. finish ( ) as usize , Ordering :: Release ) ;
152
+ } ) ;
153
+
154
+ let seed = HASH_SEED . load ( Ordering :: Acquire ) ;
155
155
156
156
let mut h = DefaultHasher :: new ( ) ;
157
- HASH . load ( SeqCst ) . hash ( & mut h) ;
157
+ seed . hash ( & mut h) ;
158
158
self . 0 . hash ( & mut h) ;
159
159
write ! ( f, "{:016x}" , h. finish( ) )
160
160
}
161
161
}
162
+
163
+ #[ cfg( test) ]
164
+ mod tests {
165
+ use super :: * ;
166
+
167
+ #[ test]
168
+ fn test_short_hash_eq ( ) {
169
+ let hash = ShortHash ( "Hello World" ) ;
170
+ let hash_str = format ! ( "{}" , hash) ;
171
+ assert_eq ! ( & hash_str, "0711bda1e8c6f44a" ) ;
172
+ }
173
+ }
0 commit comments