@@ -36,6 +36,9 @@ struct Salt2 end
3636struct NoSalt end
3737@batteries NoSalt
3838
39+ struct SaltABC; a;b;c end
40+ @batteries SaltABC typesalt = 1
41+
3942struct SErrors;a;b;c;end
4043
4144struct NoSelfCtor; a; end
@@ -91,9 +94,21 @@ struct SNoIsEqual; a; end
9194 @test_throws Exception @macroexpand @batteries SErrors nonsense= true
9295 @macroexpand @batteries SErrors kwconstructor= true
9396
94- @test hash (Salt1 ()) === hash (Salt1b ())
95- @test hash (Salt1 ()) != hash (NoSalt ())
96- @test hash (Salt1 ()) != hash (Salt2 ())
97+ @testset " typesalt" begin
98+ @test hash (Salt1 ()) === hash (Salt1b ())
99+ @test hash (Salt1 ()) != hash (NoSalt ())
100+ @test hash (Salt1 ()) != hash (Salt2 ())
101+
102+ # persistence
103+ @test hash (Salt1 ()) === 0xd39a1e58a7b0c35e
104+ @test hash (Salt1b ()) === 0xd39a1e58a7b0c35e
105+ @test hash (Salt2 ()) === 0x2f64a52e5f45d104
106+
107+ @test hash (SaltABC (1 , 2 , 3 )) === 0x92290cfd972fe54d
108+ @test hash (SaltABC (10 , 2 , 3 )) === 0xcc48b9e98b6f3ef4
109+ @test hash (SaltABC (10 , 20 , 3 )) === 0x6f8c614051f68ec7
110+ @test hash (SaltABC (10 , 20 , 30 )) === 0x90cb2b9a94741e53
111+ end
97112
98113 @test WithSelfCtor (WithSelfCtor (1 )) === WithSelfCtor (1 )
99114 @test NoSelfCtor (NoSelfCtor (1 )) != NoSelfCtor (1 )
@@ -153,3 +168,70 @@ struct Bad end
153168 @test_throws " Bad keyword argument value" @macroexpand @batteries Bad hash= :nonsense
154169 end
155170end
171+
172+ abstract type AbstractHashEqAs end
173+ function SH. hash_eq_as (x:: AbstractHashEqAs )
174+ return x. hash_eq_as (x. payload)
175+ end
176+
177+ struct HashEqAs <: AbstractHashEqAs
178+ hash_eq_as
179+ payload
180+ end
181+ SH. @batteries HashEqAs
182+ struct HashEqAsTS1 <: AbstractHashEqAs
183+ hash_eq_as
184+ payload
185+ end
186+ SH. @batteries HashEqAsTS1 typesalt = 1
187+
188+ struct HashEqAsTS1b <: AbstractHashEqAs
189+ hash_eq_as
190+ payload
191+ end
192+ SH. @batteries HashEqAsTS1b typesalt = 1
193+
194+ struct HashEqAsTS2 <: AbstractHashEqAs
195+ hash_eq_as
196+ payload
197+ end
198+ SH. @batteries HashEqAsTS2 typesalt = 2
199+
200+ @testset " hash_eq_as" begin
201+ @test HashEqAs (identity, 1 ) != HashEqAs (identity, - 1 )
202+ @test HashEqAs (abs, 1 ) == HashEqAs (abs, - 1 )
203+ @test isequal (HashEqAs (identity, 1 ), HashEqAs (x-> x, 1 ))
204+
205+ @test hash (HashEqAs (identity, 1 )) != hash (HashEqAs (identity, - 1 ))
206+ @test hash (HashEqAs (abs, 1 )) === hash (HashEqAs (abs, - 1 ))
207+ @test hash (HashEqAs (identity, 1 )) === hash (HashEqAs (x-> x, 1 ))
208+
209+ @test hash (HashEqAsTS1 (identity, 1 )) != hash (HashEqAsTS1 (identity, - 1 ))
210+ @test hash (HashEqAsTS1 (abs, 1 )) == hash (HashEqAsTS1 (abs, - 1 ))
211+ @test hash (HashEqAsTS1b (abs, 1 )) == hash (HashEqAsTS1 (abs, - 1 ))
212+ @test hash (HashEqAsTS2 (abs, 1 )) != hash (HashEqAsTS1 (abs, - 1 ))
213+
214+ @test hash (HashEqAsTS1 (x-> 2 x:: Int , 1 )) === hash (HashEqAsTS1 (identity, 2 ))
215+ @test hash (HashEqAsTS2 (x-> 2 x:: Int , 1 )) != hash (HashEqAsTS1 (identity, 2 ))
216+ @test hash (HashEqAsTS1 (identity, 1 )) === 0x486b072c90d60e64
217+ @test hash (HashEqAsTS2 (x-> 5 x, 1 )) === 0xa4360acf486c15a4
218+ end
219+
220+ mutable struct HashEqErr
221+ a
222+ b
223+ end
224+ Base. hash (:: HashEqErr , h:: UInt ) = error ()
225+ Base. isequal (:: HashEqErr , :: HashEqErr ) = error ()
226+ Base.:(== )(:: HashEqErr , :: HashEqErr ) = error ()
227+
228+ @testset " structural hash eq" begin
229+ S = HashEqErr
230+ @test SH. structural_eq (S (1 ,3 ), S (1 ,3 ))
231+ @test ! SH. structural_eq (S (1 ,NaN ), S (1 ,NaN ))
232+ @test SH. structural_isequal (S (1 ,NaN ), S (1 ,NaN ))
233+ @test ! SH. structural_isequal (S (2 ,NaN ), S (1 ,NaN ))
234+ @test SH. structural_hash (S (2 ,NaN ), UInt (0 )) != SH. structural_hash (S (1 ,NaN ), UInt (0 ))
235+ @test SH. structural_hash (S (2 ,NaN ), UInt (0 )) == SH. structural_hash (S (2 ,NaN ), UInt (0 ))
236+ @test SH. structural_hash (S (2 ,NaN ), UInt (0 )) != SH. structural_hash (S (2 ,NaN ), UInt (1 ))
237+ end
0 commit comments