main()1 void main()
2 {
3 issue19562();
4 issue15111();
5 issues16654And16764();
6 issue18918();
7 issue18925();
8 issue19005();
9 issue19204();
10 issue19262();
11 issue19568();
12 issue19582();
13 testTypeInfoArrayGetHash1();
14 testTypeInfoArrayGetHash2();
15 pr2243();
16 }
17
18 /// Check hashOf an array of void pointers or delegates is @safe.
issue19562()19 void issue19562() @nogc nothrow pure @safe
20 {
21 void*[10] val;
22 size_t h = hashOf(val[]);
23
24 alias D = void delegate();
25 D[10] ds;
26 h = hashOf(ds[]);
27 }
28
29 /// hashOf was failing for structs that had an `alias this` to a dynamic array.
issue15111()30 void issue15111()
31 {
32 void testAlias(T)()
33 {
34 static struct Foo
35 {
36 T t;
37 alias t this;
38 }
39 Foo foo;
40 static assert(is(typeof(hashOf(foo))));
41 }
42 // was fixed
43 testAlias!(int[]);
44 testAlias!(int*);
45 // was not affected
46 testAlias!int;
47 testAlias!(void delegate());
48 testAlias!(string[string]);
49 testAlias!(int[8]);
50 }
51
issues16654And16764()52 void issues16654And16764()
53 {
54 auto a = [1];
55 auto b = a.dup;
56 assert(hashOf(a) == hashOf(b));
57 }
58
59 /// Check hashOf dynamic array of scalars is usable in @safe code.
issue18918()60 void issue18918() nothrow pure @safe
61 {
62 const _ = (() @nogc => hashOf("abc"))();
63
64 static struct S { string array; }
65 auto s1 = S("abc");
66 auto s2 = S(s1.array.idup);
67 assert(hashOf(s1) == hashOf(s2));
68 enum e = hashOf(S("abc"));
69 assert(hashOf(s1) == e);
70 }
71
72 /// Check hashOf struct of scalar fields is usable in @safe code.
issue18925()73 void issue18925() @nogc nothrow pure @safe
74 {
75
76 static struct S { int a; int b; }
77 auto h = hashOf(S.init);
78 }
79
issue19005()80 void issue19005() @nogc nothrow pure @safe
81 {
82 enum Month : ubyte
83 {
84 jan = 1
85 }
86 static struct Date
87 {
88 short _year;
89 Month _month;
90 ubyte _day;
91 }
92 Date date;
93 auto hash = date.hashOf;
94 }
95
96 /// Accept SIMD vectors.
issue19204()97 void issue19204() @nogc nothrow pure @safe
98 {
99 version (D_SIMD)
100 {
101 static import simd = core.simd;
102 static if (is(simd.int4)) // __traits(isArithmetic)
103 {{
104 enum simd.int4 val = [1,2,3,4];
105 enum ctfeHash = hashOf(val);
106 simd.int4 rtVal = val;
107 auto rtHash = hashOf(rtVal);
108 assert(ctfeHash == rtHash);
109 }}
110 static if (is(simd.void16)) // non __traits(isArithmetic)
111 {{
112 auto h = hashOf(simd.void16.init);
113 }}
114 static if (is(simd.float4)) // __traits(isArithmetic) and __traits(isFloating)
115 {{
116 enum simd.float4 val = [1.1f, 2.2f, 3.3f, 4.4f];
117 enum ctfeHash = hashOf(val);
118 simd.float4 rtVal = val;
119 auto rtHash = hashOf(rtVal);
120 assert(ctfeHash == rtHash);
121 }}
122 }
123 }
124
125 /// hashOf associative array should infer nothrow
issue19262()126 void issue19262() nothrow
127 {
128 int[int] aa;
129 auto h = hashOf(aa);
130 h = hashOf(aa, h);
131 }
132
133 /// hashOf should not unnecessarily call a struct's fields' postblits & dtors in CTFE
issue19568()134 void issue19568()
135 {
136 static struct S1
137 {
138 @disable this(this);
139
140 ~this() @nogc nothrow
141 {
142 import core.stdc.stdio;
143 if (mptr) puts("impure");
144 }
145
146 size_t[2] pad;
147 void* mptr;
148 }
149
150 static struct S2
151 {
152 @disable this(this);
153
154 ~this() @nogc nothrow
155 {
156 import core.stdc.stdio;
157 if (fd != -1) puts("impure");
158 }
159
160 int fd = -1;
161 S1 s1;
162 }
163
164 static struct S3
165 {
166 private S2 s2;
167 }
168
169 S3 s3;
170 size_t h = ((ref S3 s3) pure => hashOf(s3))(s3);
171 }
172
173 /// Check core.internal.convert.toUbyte in CTFE for arrays works with
174 /// reference type elements and doesn't call postblits/dtors.
issue19582()175 void issue19582()
176 {
177 import core.internal.convert : toUbyte;
178 final static class C : Object {}
179 enum b1 = (() @nogc nothrow pure @safe { C[10] o; return toUbyte(o[])[0]; })();
180
181 static struct S
182 {
183 int x;
184 @disable this(this);
185 ~this() @nogc nothrow
186 {
187 import core.stdc.stdio : puts;
188 if (x) puts("impure");
189 }
190 }
191 enum b2 = () {
192 S[10] a;
193 return ((const S[] a) @nogc nothrow pure @safe => toUbyte(a))(a);
194 }();
195 }
196
197 /// Tests ensure TypeInfo_Array.getHash uses element hash functions instead
198 /// of hashing array data.
testTypeInfoArrayGetHash1()199 void testTypeInfoArrayGetHash1()
200 {
201 class C
202 {
203 int i;
204 this(in int i) { this.i = i; }
205 override hash_t toHash() { return 0; }
206 }
207 C[] a1 = [new C(11)], a2 = [new C(12)];
208 assert(typeid(C[]).getHash(&a1) == typeid(C[]).getHash(&a2));
209 }
210
211 /// ditto
testTypeInfoArrayGetHash2()212 void testTypeInfoArrayGetHash2()
213 {
214 struct S
215 {
216 int i;
217 hash_t toHash() const @safe nothrow { return 0; }
218 }
219 S[] a1 = [S(11)], a2 = [S(12)];
220 assert(typeid(S[]).getHash(&a1) == typeid(S[]).getHash(&a2));
221 }
222
223 /++
224 Use the new `core.internal.hash.hashOf` in all `TypeInfo.getHash` instead of
225 the `old rt.util.hash.hashOf`. Also make `typeid(T).getHash(&val)` get the
226 same result as `hashOf(val)`.
227 +/
pr2243()228 void pr2243()
229 {
230 static struct Foo
231 {
232 int a = 99;
233 float b = 4.0;
234 size_t toHash() const pure @safe nothrow
235 {
236 return a;
237 }
238 }
239
240 static struct Bar
241 {
242 char c = 'x';
243 int a = 99;
244 float b = 4.0;
245 void* d = null;
246 }
247
248 static struct Boom
249 {
250 char c = 'M';
251 int* a = null;
252 }
253
254 static struct Plain
255 {
256 int a = 1;
257 int b = 2;
258 }
259
260 interface IBoo
261 {
262 void boo();
263 }
264
265 static class Boo: IBoo
266 {
267 override void boo()
268 {
269 }
270
271 override size_t toHash()
272 {
273 return 1;
274 }
275 }
276
277 static struct Goo
278 {
279 size_t toHash() pure @safe nothrow
280 {
281 return 1;
282 }
283 }
284
285 enum Gun: long
286 {
287 A = 99,
288 B = 17
289 }
290
291 enum double dexpr = 3.14;
292 enum float fexpr = 2.71;
293 enum wstring wsexpr = "abcdef"w;
294 enum string csexpr = "abcdef";
295 enum int iexpr = 7;
296 enum long lexpr = 42;
297 enum int[2][3] saexpr = [[1, 2], [3, 4], [5, 6]];
298 enum int[] daexpr = [7,8,9];
299 enum Foo thsexpr = Foo();
300 enum Bar vsexpr = Bar();
301 enum int[int] aaexpr = [99:2, 12:6, 45:4];
302 enum Gun eexpr = Gun.A;
303 enum cdouble cexpr = 7+4i;
304 enum Foo[] staexpr = [Foo(), Foo(), Foo()];
305 enum Bar[] vsaexpr = [Bar(), Bar(), Bar()];
306 enum realexpr = 7.88;
307 enum raexpr = [8.99L+86i, 3.12L+99i, 5.66L+12i];
308 enum nullexpr = null;
309 enum plstr = Plain();
310 enum plarrstr = [Plain(), Plain(), Plain()];
311 //No CTFE:
312 Boom rstructexpr = Boom();
313 Boom[] rstrarrexpr = [Boom(), Boom(), Boom()];
314 int delegate() dgexpr = (){return 78;};
315 void* ptrexpr = &dgexpr;
316
317
318 //CTFE hashes
319 enum h1 = dexpr.hashOf();
320 enum h2 = fexpr.hashOf();
321 enum h3 = wsexpr.hashOf();
322 enum h4 = csexpr.hashOf();
323 enum h5 = iexpr.hashOf();
324 enum h6 = lexpr.hashOf();
325 enum h7 = saexpr.hashOf();
326 enum h8 = daexpr.hashOf();
327 enum h9 = thsexpr.hashOf();
328 enum h10 = vsexpr.hashOf();
329 enum h11 = aaexpr.hashOf();
330 enum h12 = eexpr.hashOf();
331 enum h13 = cexpr.hashOf();
332 enum h14 = hashOf(new Boo);
333 enum h15 = staexpr.hashOf();
334 enum h16 = hashOf([new Boo, new Boo, new Boo]);
335 enum h17 = hashOf([cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo]);
336 enum h18 = hashOf(cast(IBoo)new Boo);
337 enum h19 = vsaexpr.hashOf();
338 enum h20 = hashOf(cast(Foo[3])staexpr);
339
340 //BUG: cannot cast [Boo(), Boo(), Boo()][0] to object.Object at compile time
341 auto h21 = hashOf(cast(Boo[3])[new Boo, new Boo, new Boo]);
342 auto h22 = hashOf(cast(IBoo[3])[cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo]);
343 enum h23 = hashOf(cast(Bar[3])vsaexpr);
344
345 //NO CTFE (Compute, but don't check correctness):
346 auto h24 = rstructexpr.hashOf();
347 auto h25 = rstrarrexpr.hashOf();
348 auto h26 = dgexpr.hashOf();
349 auto h27 = ptrexpr.hashOf();
350
351 enum h28 = realexpr.hashOf();
352 enum h29 = raexpr.hashOf();
353 enum h30 = nullexpr.hashOf();
354 enum h31 = plstr.hashOf();
355 enum h32 = plarrstr.hashOf();
356 enum h33 = hashOf(cast(Plain[3])plarrstr);
357
358 auto v1 = dexpr;
359 auto v2 = fexpr;
360 auto v3 = wsexpr;
361 auto v4 = csexpr;
362 auto v5 = iexpr;
363 auto v6 = lexpr;
364 auto v7 = saexpr;
365 auto v8 = daexpr;
366 auto v9 = thsexpr;
367 auto v10 = vsexpr;
368 auto v11 = aaexpr;
369 auto v12 = eexpr;
370 auto v13 = cexpr;
371 auto v14 = new Boo;
372 auto v15 = staexpr;
373 auto v16 = [new Boo, new Boo, new Boo];
374 auto v17 = [cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo];
375 auto v18 = cast(IBoo)new Boo;
376 auto v19 = vsaexpr;
377 auto v20 = cast(Foo[3])staexpr;
378 auto v21 = cast(Boo[3])[new Boo, new Boo, new Boo];
379 auto v22 = cast(IBoo[3])[cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo];
380 auto v23 = cast(Bar[3])vsaexpr;
381 auto v30 = null;
382 auto v31 = plstr;
383 auto v32 = plarrstr;
384 auto v33 = cast(Plain[3])plarrstr;
385
386 //NO CTFE:
387 auto v24 = rstructexpr;
388 auto v25 = rstrarrexpr;
389 auto v26 = dgexpr;
390 auto v27 = ptrexpr;
391 auto v28 = realexpr;
392 auto v29 = raexpr;
393
394 //runtime hashes
395 auto rth1 = hashOf(v1);
396 auto rth2 = hashOf(v2);
397 auto rth3 = hashOf(v3);
398 auto rth4 = hashOf(v4);
399 auto rth5 = hashOf(v5);
400 auto rth6 = hashOf(v6);
401 auto rth7 = hashOf(v7);
402 auto rth8 = hashOf(v8);
403 auto rth9 = hashOf(v9);
404 auto rth10 = hashOf(v10);
405 auto rth11 = hashOf(v11);
406 auto rth12 = hashOf(v12);
407 auto rth13 = hashOf(v13);
408 auto rth14 = hashOf(v14);
409 auto rth15 = hashOf(v15);
410 auto rth16 = hashOf(v16);
411 auto rth17 = hashOf(v17);
412 auto rth18 = hashOf(v18);
413 auto rth19 = hashOf(v19);
414 auto rth20 = hashOf(v20);
415 auto rth21 = hashOf(v21);
416 auto rth22 = hashOf(v22);
417 auto rth23 = hashOf(v23);
418 auto rth30 = hashOf(v30);
419 //NO CTFE:
420 auto rth24 = hashOf(v24);
421 auto rth25 = hashOf(v25);
422 auto rth26 = hashOf(v26);
423 auto rth27 = hashOf(v27);
424 auto rth28 = hashOf(v28);
425 auto rth29 = hashOf(v29);
426
427 auto rth31 = hashOf(v31);
428 auto rth32 = hashOf(v32);
429 auto rth33 = hashOf(v33);
430
431 assert(h1 == rth1);
432 assert(h2 == rth2);
433 assert(h3 == rth3);
434 assert(h4 == rth4);
435 assert(h5 == rth5);
436 assert(h6 == rth6);
437 assert(h7 == rth7);
438 assert(h8 == rth8);
439 assert(h9 == rth9);
440 assert(h10 == rth10);
441 assert(h11 == rth11);
442 assert(h12 == rth12);
443 assert(h13 == rth13);
444 assert(h14 == rth14);
445 assert(h15 == rth15);
446 assert(h16 == rth16);
447 assert(h17 == rth17);
448 assert(h18 == rth18);
449 assert(h19 == rth19);
450 assert(h20 == rth20);
451 assert(h21 == rth21);
452 assert(h22 == rth22);
453 assert(h23 == rth23);
454 /*assert(h24 == rth24);
455 assert(h25 == rth25);
456 assert(h26 == rth26);
457 assert(h27 == rth27);
458 assert(h28 == rth28);
459 assert(h29 == rth29);*/
460 assert(h30 == rth30);
461 assert(h31 == rth31);
462 assert(h32 == rth32);
463 assert(h33 == rth33);
464
465 // https://issues.dlang.org/show_bug.cgi?id=18932
466 assert(hashOf(null, 0) != hashOf(null, 123456789));
467
468 static size_t tiHashOf(T)(T var)
469 {
470 return typeid(T).getHash(&var);
471 }
472
473 auto tih1 = tiHashOf(v1);
474 auto tih2 = tiHashOf(v2);
475 auto tih3 = tiHashOf(v3);
476 auto tih4 = tiHashOf(v4);
477 auto tih5 = tiHashOf(v5);
478 auto tih6 = tiHashOf(v6);
479 auto tih7 = tiHashOf(v7);
480 auto tih8 = tiHashOf(v8);
481 auto tih9 = tiHashOf(v9);
482 auto tih10 = tiHashOf(v10);
483 auto tih11 = tiHashOf(v11);
484 auto tih12 = tiHashOf(v12);
485 auto tih13 = tiHashOf(v13);
486 auto tih14 = tiHashOf(v14);
487 auto tih15 = tiHashOf(v15);
488 auto tih16 = tiHashOf(v16);
489 auto tih17 = tiHashOf(v17);
490 auto tih18 = tiHashOf(v18);
491 auto tih19 = tiHashOf(v19);
492 auto tih20 = tiHashOf(v20);
493 auto tih21 = tiHashOf(v21);
494 auto tih22 = tiHashOf(v22);
495 auto tih23 = tiHashOf(v23);
496 auto tih24 = tiHashOf(v24);
497 auto tih25 = tiHashOf(v25);
498 auto tih26 = tiHashOf(v26);
499 auto tih27 = tiHashOf(v27);
500 auto tih28 = tiHashOf(v28);
501 auto tih29 = tiHashOf(v29);
502 auto tih30 = tiHashOf(v30);
503 auto tih31 = tiHashOf(v31);
504 auto tih32 = tiHashOf(v32);
505 auto tih33 = tiHashOf(v33);
506
507 assert(tih1 == rth1);
508 assert(tih2 == rth2);
509 assert(tih3 == rth3);
510 assert(tih4 == rth4);
511 assert(tih5 == rth5);
512 assert(tih6 == rth6);
513 assert(tih7 == rth7);
514 assert(tih8 == rth8);
515 assert(tih9 == rth9);
516 //assert(tih10 == rth10); // need compiler-generated __xtoHash changes
517 assert(tih11 == rth11);
518 assert(tih12 == rth12);
519 assert(tih13 == rth13);
520 assert(tih14 == rth14);
521 assert(tih15 == rth15);
522 assert(tih16 == rth16);
523 assert(tih17 == rth17);
524 assert(tih18 == rth18);
525 //assert(tih19 == rth19); // need compiler-generated __xtoHash changes
526 assert(tih20 == rth20);
527 assert(tih21 == rth21);
528 assert(tih22 == rth22);
529 //assert(tih23 == rth23); // need compiler-generated __xtoHash changes
530 //assert(tih24 == rth24);
531 //assert(tih25 == rth25);
532 assert(tih26 == rth26);
533 assert(tih27 == rth27);
534 assert(tih28 == rth28);
535 assert(tih29 == rth29);
536 assert(tih30 == rth30);
537 assert(tih31 == rth31);
538 assert(tih32 == rth32);
539 assert(tih33 == rth33);
540 }
541