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. 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. 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 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. 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. 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 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. 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 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 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. 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. 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 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 +/ 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