1 
2 // Test operator overloading
3 
4 import core.stdc.stdio;
5 
6 /**************************************/
7 
8 class A1
9 {
opAdd(int i)10     int opAdd(int i) { return 7 + i; }
11 }
12 
test1()13 void test1()
14 {
15     A1 a = new A1();
16     int i;
17 
18     i = a + 3;
19     assert(i == 10);
20 
21     i = 4 + a;
22     assert(i == 11);
23 }
24 
25 /**************************************/
26 
27 class A2
28 {
opDiv(int i)29     int opDiv(int i)   { return 9 + i; }
opDiv_r(int i)30     int opDiv_r(int i) { return 17 + i; }
31 }
32 
test2()33 void test2()
34 {
35     A2 a = new A2();
36     int i;
37 
38     i = a / 3;
39     assert(i == 12);
40 
41     i = 4 / a;
42     assert(i == 21);
43 }
44 
45 /**************************************/
46 
47 class C1
48 {
49 }
50 
51 class C2
52 {
opAdd(D1 d)53     int opAdd(D1 d)   { return 1; }
opAdd(D2 d)54     int opAdd(D2 d)   { return 2; }
opAdd(D3 d)55     int opAdd(D3 d)   { return 3; }
opAdd(D4 d)56     int opAdd(D4 d)   { return 4; }
57 }
58 
59 class C3
60 {
opAdd_r(D1 d)61     int opAdd_r(D1 d) { return 5; }
opAdd_r(D2 d)62     int opAdd_r(D2 d) { return 6; }
opAdd_r(D3 d)63     int opAdd_r(D3 d) { return 7; }
opAdd_r(D4 d)64     int opAdd_r(D4 d) { return 8; }
65 }
66 
67 class C4
68 {
opAdd(D1 d)69     int opAdd(D1 d)   { return 9; }
opAdd(D2 d)70     int opAdd(D2 d)   { return 10; }
opAdd(D3 d)71     int opAdd(D3 d)   { return 11; }
opAdd(D4 d)72     int opAdd(D4 d)   { return 12; }
73 
opAdd_r(D1 d)74     int opAdd_r(D1 d) { return 13; }
opAdd_r(D2 d)75     int opAdd_r(D2 d) { return 14; }
opAdd_r(D3 d)76     int opAdd_r(D3 d) { return 15; }
opAdd_r(D4 d)77     int opAdd_r(D4 d) { return 16; }
78 }
79 
80 class D1
81 {
82 }
83 
84 class D2
85 {
opAdd(C1 c)86     int opAdd(C1 c)   { return 17; }
opAdd(C2 d)87     int opAdd(C2 d)   { return 18; }
opAdd(C3 d)88     int opAdd(C3 d)   { return 19; }
opAdd(C4 d)89     int opAdd(C4 d)   { return 20; }
90 }
91 
92 class D3
93 {
opAdd_r(C1 d)94     int opAdd_r(C1 d) { return 21; }
opAdd_r(C2 d)95     int opAdd_r(C2 d) { return 22; }
opAdd_r(C3 d)96     int opAdd_r(C3 d) { return 23; }
opAdd_r(C4 d)97     int opAdd_r(C4 d) { return 24; }
98 }
99 
100 class D4
101 {
opAdd(C1 d)102     int opAdd(C1 d)   { return 25; }
opAdd(C2 d)103     int opAdd(C2 d)   { return 26; }
opAdd(C3 d)104     int opAdd(C3 d)   { return 27; }
opAdd(C4 d)105     int opAdd(C4 d)   { return 28; }
106 
opAdd_r(C1 d)107     int opAdd_r(C1 d) { return 29; }
opAdd_r(C2 d)108     int opAdd_r(C2 d) { return 30; }
opAdd_r(C3 d)109     int opAdd_r(C3 d) { return 31; }
opAdd_r(C4 d)110     int opAdd_r(C4 d) { return 32; }
111 }
112 
113 
114 
test3()115 void test3()
116 {
117     C1 c1 = new C1();
118     C2 c2 = new C2();
119     C3 c3 = new C3();
120     C4 c4 = new C4();
121     D1 d1 = new D1();
122     D2 d2 = new D2();
123     D3 d3 = new D3();
124     D4 d4 = new D4();
125 
126     int i;
127 
128   version (ADD_R)
129   {
130     //i = c1 + d1;    assert(i == );
131     i = c1 + d2;    assert(i == 17);
132     i = c1 + d3;    assert(i == 21);
133     i = c1 + d4;    assert(i == 29);
134 
135     i = c2 + d1;    assert(i == 1);
136     i = c2 + d2;    assert(i == 2);
137     i = c2 + d3;    assert(i == 3);
138     i = c2 + d4;    assert(i == 4);
139 
140     //i = c3 + d1;    assert(i == );
141     i = c3 + d2;    assert(i == 19);
142     i = c3 + d3;    assert(i == 23);
143     i = c3 + d4;    assert(i == 31);
144 
145     i = c4 + d1;    assert(i == 9);
146     i = c4 + d2;    assert(i == 10);
147     i = c4 + d3;    assert(i == 11);
148     i = c4 + d4;    assert(i == 12);
149 
150     //i = d1 + c1;    assert(i == );
151     i = d1 + c2;    assert(i == 1);
152     i = d1 + c3;    assert(i == 5);
153     i = d1 + c4;    assert(i == 13);
154 
155     i = d2 + c1;    assert(i == 17);
156     i = d2 + c2;    assert(i == 18);
157     i = d2 + c3;    assert(i == 19);
158     i = d2 + c4;    assert(i == 20);
159 
160     //i = d3 + c1;    assert(i == );
161     i = d3 + c2;    assert(i == 3);
162     i = d3 + c3;    assert(i == 7);
163     i = d3 + c4;    assert(i == 15);
164 
165     i = d4 + c1;    assert(i == 25);
166     i = d4 + c2;    assert(i == 26);
167     i = d4 + c3;    assert(i == 27);
168     i = d4 + c4;    assert(i == 28);
169   }
170   else
171   {
172     //i = c1 + d1;    assert(i == );
173     i = c1 + d2;    assert(i == 17);
174 //    i = c1 + d3;    assert(i == 21);
175     i = c1 + d4;    assert(i == 29);
176 
177     i = c2 + d1;    assert(i == 1);
178     i = c2 + d2;    assert(i == 2);
179 //    i = c2 + d3;    assert(i == 3);
180 //    i = c2 + d4;    assert(i == 4);
181 
182     //i = c3 + d1;    assert(i == );
183 //    i = c3 + d2;    printf("i = %d\n", i); assert(i == 19);
184 //    i = c3 + d3;    assert(i == 23);
185     i = c3 + d4;    assert(i == 31);
186 
187     i = c4 + d1;    assert(i == 9);
188     i = c4 + d2;    assert(i == 10);
189 //    i = c4 + d3;    assert(i == 11);
190 //    i = c4 + d4;    assert(i == 12);
191 
192     //i = d1 + c1;    assert(i == );
193     i = d1 + c2;    assert(i == 1);
194 //    i = d1 + c3;    assert(i == 5);
195     i = d1 + c4;    assert(i == 13);
196 
197     i = d2 + c1;    assert(i == 17);
198     i = d2 + c2;    assert(i == 18);
199 //    i = d2 + c3;    assert(i == 19);
200 //    i = d2 + c4;    assert(i == 20);
201 
202     //i = d3 + c1;    assert(i == );
203 //    i = d3 + c2;    assert(i == 3);
204 //    i = d3 + c3;    assert(i == 7);
205     i = d3 + c4;    assert(i == 15);
206 
207     i = d4 + c1;    assert(i == 25);
208     i = d4 + c2;    assert(i == 26);
209 //    i = d4 + c3;    assert(i == 27);
210 //    i = d4 + c4;    assert(i == 28);
211   }
212 }
213 
214 /**************************************/
215 
216 struct Foo4
217 {
218     int a;
opCmpFoo4219     int opCmp(Foo4 b)
220     {
221         return a < b.a;
222     }
223 }
224 
test4()225 void test4()
226 {
227    Foo4 a;
228    Foo4 b;
229 
230    assert(a <= b);
231 }
232 
233 /**************************************/
234 
235 class A5
236 {
opNeg()237     int opNeg()     { return 10; }
opCom()238     int opCom()     { return 11; }
opPostInc()239     int opPostInc() { return 12; }
opPostDec()240     int opPostDec() { return 13; }
241 
opAdd(int j)242     int opAdd(int j)     { return 14; }
opSub(int j)243     int opSub(int j)     { return 15; }
opSub_r(int j)244     int opSub_r(int j)   { return 16; }
opMul(int j)245     int opMul(int j)     { return 17; }
opDiv(int j)246     int opDiv(int j)     { return 18; }
opDiv_r(int j)247     int opDiv_r(int j)   { return 19; }
opMod(int j)248     int opMod(int j)     { return 20; }
opMod_r(int j)249     int opMod_r(int j)   { return 21; }
opAnd(int j)250     int opAnd(int j)     { return 22; }
opOr(int j)251     int opOr(int j)      { return 23; }
opXor(int j)252     int opXor(int j)     { return 24; }
opShl(int j)253     int opShl(int j)     { return 25; }
opShl_r(int j)254     int opShl_r(int j)   { return 26; }
opShr(int j)255     int opShr(int j)     { return 27; }
opShr_r(int j)256     int opShr_r(int j)   { return 28; }
opUShr(int j)257     int opUShr(int j)    { return 29; }
opUShr_r(int j)258     int opUShr_r(int j)  { return 30; }
opCat(int j)259     int opCat(int j)     { return 31; }
opCat_r(int j)260     int opCat_r(int j)   { return 32; }
opEquals(int j)261     int opEquals(int j)  { return 33; }
opCmp(int j)262     int opCmp(int j)     { return 34; }
opAddAssign(int j)263     int opAddAssign(int j)  { return 35; }
opSubAssign(int j)264     int opSubAssign(int j)  { return 36; }
opMulAssign(int j)265     int opMulAssign(int j)  { return 37; }
opDivAssign(int j)266     int opDivAssign(int j)  { return 38; }
opModAssign(int j)267     int opModAssign(int j)  { return 39; }
opAndAssign(int j)268     int opAndAssign(int j)  { return 40; }
opOrAssign(int j)269     int opOrAssign(int j)   { return 41; }
opXorAssign(int j)270     int opXorAssign(int j)  { return 42; }
opShlAssign(int j)271     int opShlAssign(int j)  { return 43; }
opShrAssign(int j)272     int opShrAssign(int j)  { return 44; }
opUShrAssign(int j)273     int opUShrAssign(int j) { return 45; }
opCatAssign(int j)274     int opCatAssign(int j)  { return 46; }
275 }
276 
test5()277 void test5()
278 {
279     A5 a = new A5();
280     int i;
281 
282     i = -a;
283     assert(i == 10);
284 
285     i = ~a;
286     assert(i == 11);
287 
288     i = a++;
289     assert(i == 12);
290 
291     i = a--;
292     assert(i == 13);
293 
294     i = a + 1;
295     assert(i == 14);
296 
297     i = a - 1;
298     assert(i == 15);
299 
300     i = 1 - a;
301     assert(i == 16);
302 
303     i = a * 1;
304     assert(i == 17);
305 
306     i = a / 1;
307     assert(i == 18);
308 
309     i = 1 / a;
310     assert(i == 19);
311 
312     i = a % 1;
313     assert(i == 20);
314 
315     i = 1 % a;
316     assert(i == 21);
317 
318     i = a & 1;
319     assert(i == 22);
320 
321     i = a | 1;
322     assert(i == 23);
323 
324     i = a ^ 1;
325     assert(i == 24);
326 
327     i = a << 1;
328     assert(i == 25);
329 
330     i = 1 << a;
331     assert(i == 26);
332 
333     i = a >> 1;
334     assert(i == 27);
335 
336     i = 1 >> a;
337     assert(i == 28);
338 
339     i = a >>> 1;
340     assert(i == 29);
341 
342     i = 1 >>> a;
343     assert(i == 30);
344 
345     i = a ~ 1;
346     assert(i == 31);
347 
348     i = 1 ~ a;
349     assert(i == 32);
350 
351     i = a == 1;
352     assert(i == 33);
353     i = 1 == a;
354     assert(i == 33);
355     i = a != 1;
356     assert(i == 0);
357     i = 1 != a;
358     assert(i == 0);
359 
360     i = a < 1;
361     assert(i == 0);
362     i = a <= 1;
363     assert(i == 0);
364     i = a > 1;
365     assert(i == 1);
366     i = a >= 1;
367     assert(i == 1);
368 
369     i = 1 < a;
370 printf("i = %d\n", i);
371     assert(i == 1);
372     i = 1 <= a;
373     assert(i == 1);
374     i = 1 > a;
375     assert(i == 0);
376     i = 1 >= a;
377     assert(i == 0);
378 
379     i = (a += 1);
380     assert(i == 35);
381     i = ++a;
382     assert(i == 35);
383 
384     i = (a -= 1);
385     assert(i == 36);
386     i = --a;
387     assert(i == 36);
388 
389     i = (a *= 1);
390     assert(i == 37);
391 
392     i = (a /= 1);
393     assert(i == 38);
394 
395     i = (a %= 1);
396     assert(i == 39);
397 
398     i = (a &= 1);
399     assert(i == 40);
400 
401     i = (a |= 1);
402     assert(i == 41);
403 
404     i = (a ^= 1);
405     assert(i == 42);
406 
407     i = (a <<= 1);
408     assert(i == 43);
409 
410     i = (a >>= 1);
411     assert(i == 44);
412 
413     i = (a >>>= 1);
414     assert(i == 45);
415 
416     i = (a ~= 1);
417     assert(i == 46);
418 }
419 
420 /*********************************/
421 
422 struct A6
423 {
opNegA6424     int opNeg()     { return 10; }
opComA6425     int opCom()     { return 11; }
opPostIncA6426     int opPostInc() { return 12; }
opPostDecA6427     int opPostDec() { return 13; }
428 
opAddA6429     int opAdd(int j)     { return 14; }
opSubA6430     int opSub(int j)     { return 15; }
opSub_rA6431     int opSub_r(int j)   { return 16; }
opMulA6432     int opMul(int j)     { return 17; }
opDivA6433     int opDiv(int j)     { return 18; }
opDiv_rA6434     int opDiv_r(int j)   { return 19; }
opModA6435     int opMod(int j)     { return 20; }
opMod_rA6436     int opMod_r(int j)   { return 21; }
opAndA6437     int opAnd(int j)     { return 22; }
opOrA6438     int opOr(int j)      { return 23; }
opXorA6439     int opXor(int j)     { return 24; }
opShlA6440     int opShl(int j)     { return 25; }
opShl_rA6441     int opShl_r(int j)   { return 26; }
opShrA6442     int opShr(int j)     { return 27; }
opShr_rA6443     int opShr_r(int j)   { return 28; }
opUShrA6444     int opUShr(int j)    { return 29; }
opUShr_rA6445     int opUShr_r(int j)  { return 30; }
opCatA6446     int opCat(int j)     { return 31; }
opCat_rA6447     int opCat_r(int j)   { return 32; }
opEqualsA6448     int opEquals(int j)      { return 33; }
opEqualsA6449     const bool opEquals(const ref A6)      { return false; }
opCmpA6450     int opCmp(int j)     { return 34; }
opAddAssignA6451     int opAddAssign(int j)  { return 35; }
opSubAssignA6452     int opSubAssign(int j)  { return 36; }
opMulAssignA6453     int opMulAssign(int j)  { return 37; }
opDivAssignA6454     int opDivAssign(int j)  { return 38; }
opModAssignA6455     int opModAssign(int j)  { return 39; }
opAndAssignA6456     int opAndAssign(int j)  { return 40; }
opOrAssignA6457     int opOrAssign(int j)   { return 41; }
opXorAssignA6458     int opXorAssign(int j)  { return 42; }
opShlAssignA6459     int opShlAssign(int j)  { return 43; }
opShrAssignA6460     int opShrAssign(int j)  { return 44; }
opUShrAssignA6461     int opUShrAssign(int j) { return 45; }
opCatAssignA6462     int opCatAssign(int j)  { return 46; }
463 }
464 
test6()465 void test6()
466 {
467     A6 a;
468     int i;
469 
470     i = -a;
471     assert(i == 10);
472 
473     i = ~a;
474     assert(i == 11);
475 
476     i = a++;
477     assert(i == 12);
478 
479     i = a--;
480     assert(i == 13);
481 
482     i = a + 1;
483     assert(i == 14);
484 
485     i = a - 1;
486     assert(i == 15);
487 
488     i = 1 - a;
489     assert(i == 16);
490 
491     i = a * 1;
492     assert(i == 17);
493 
494     i = a / 1;
495     assert(i == 18);
496 
497     i = 1 / a;
498     assert(i == 19);
499 
500     i = a % 1;
501     assert(i == 20);
502 
503     i = 1 % a;
504     assert(i == 21);
505 
506     i = a & 1;
507     assert(i == 22);
508 
509     i = a | 1;
510     assert(i == 23);
511 
512     i = a ^ 1;
513     assert(i == 24);
514 
515     i = a << 1;
516     assert(i == 25);
517 
518     i = 1 << a;
519     assert(i == 26);
520 
521     i = a >> 1;
522     assert(i == 27);
523 
524     i = 1 >> a;
525     assert(i == 28);
526 
527     i = a >>> 1;
528     assert(i == 29);
529 
530     i = 1 >>> a;
531     assert(i == 30);
532 
533     i = a ~ 1;
534     assert(i == 31);
535 
536     i = 1 ~ a;
537     assert(i == 32);
538 
539     i = a == 1;
540     assert(i == 33);
541     i = 1 == a;
542     assert(i == 33);
543     i = a != 1;
544     assert(i == 0);
545     i = 1 != a;
546     assert(i == 0);
547 
548     i = a < 1;
549     assert(i == 0);
550     i = a <= 1;
551     assert(i == 0);
552     i = a > 1;
553     assert(i == 1);
554     i = a >= 1;
555     assert(i == 1);
556 
557     i = 1 < a;
558     assert(i == 1);
559     i = 1 <= a;
560     assert(i == 1);
561     i = 1 > a;
562     assert(i == 0);
563     i = 1 >= a;
564     assert(i == 0);
565 
566     i = (a += 1);
567     assert(i == 35);
568     i = ++a;
569     assert(i == 35);
570 
571     i = (a -= 1);
572     assert(i == 36);
573     i = --a;
574     assert(i == 36);
575 
576     i = (a *= 1);
577     assert(i == 37);
578 
579     i = (a /= 1);
580     assert(i == 38);
581 
582     i = (a %= 1);
583     assert(i == 39);
584 
585     i = (a &= 1);
586     assert(i == 40);
587 
588     i = (a |= 1);
589     assert(i == 41);
590 
591     i = (a ^= 1);
592     assert(i == 42);
593 
594     i = (a <<= 1);
595     assert(i == 43);
596 
597     i = (a >>= 1);
598     assert(i == 44);
599 
600     i = (a >>>= 1);
601     assert(i == 45);
602 
603     i = (a ~= 1);
604     assert(i == 46);
605 }
606 
607 
608 /**************************************/
609 
610 struct Foo7
611 {
opSliceFoo7612     int opSlice() { return 7; }
opSliceFoo7613     int opSlice(int i, int j) { return i * (j + 1); }
614 }
615 
test7()616 void test7()
617 {
618     Foo7 f;
619     int i;
620 
621     i = f[];
622     assert(i == 7);
623     i = f[3..4];
624     assert(i == 15);
625 }
626 
627 /**************************************/
628 
629 interface IWriter
630 {
631         int opShl (string i);
632         int opShl (int i);
633 }
634 
635 class Writer : IWriter
636 {
opShl(string i)637     int opShl (string i)
638     {
639         printf("Writer.opShl(char[])\n");
640         return 1;
641     }
642 
opShl(int i)643     int opShl (int i)
644     {
645         printf("Writer.opShl(int)\n");
646         return 2;
647     }
648 }
649 
650 class BinaryWriter : Writer
651 {
652     alias Writer.opShl opShl;
653 
opShl(int i)654     override int opShl (int i)
655     {
656         printf("BinaryWriter.opShl(int)\n");
657         return 3;
658     }
659 }
660 
test8()661 void test8()
662 {
663     BinaryWriter bw = new BinaryWriter();
664     int i;
665 
666     i = bw << "test";
667     assert(i == 1);
668     i = bw << 1;
669     assert(i == 3);
670 }
671 
672 /**************************************/
673 
674 struct A9
675 {
opCastA9676     int opCast() { return 28; }
677 }
678 
test9()679 void test9()
680 {
681     A9 a;
682 
683     long i = cast(long)a;
684     assert(i == 28);
685 }
686 
687 /**************************************/
688 
689 class A10
690 {
opAdd(int i)691     int opAdd(int i) { return i + 1; }
692 }
693 
694 class B10
695 {
opAdd_r(A10 a)696     int opAdd_r(A10 a) { return 3; }
697 }
698 
test10()699 void test10()
700 {
701     int i;
702     A10 a = new A10();
703 
704     i = a + 1;
705     printf("a + 1 = %d\n", i);
706     assert(i == 2);
707 
708     i = 1 + a;
709     printf("1 + a = %d\n", i);
710     assert(i == 2);
711 
712     B10 b = new B10();
713     i = a + b;
714     printf("a + b = %d\n", i);
715     assert(i == 3);
716 
717     i = b + a;
718     printf("b + a = %d\n", i);
719     assert(i == 3);
720 
721 //    i = b + 3;
722 }
723 
724 /**************************************/
725 
726 class A11
727 {
opIndex(int i)728     int opIndex(int i) { return i; }
opIndexAssign(int value,int i)729     int opIndexAssign(int value, int i) { return value * 10 + i; }
730 }
731 
test11()732 void test11()
733 {
734     int i;
735     A11 a = new A11();
736 
737     i = a[5];
738     assert(i == 5);
739     i = (a[4] = 6);
740     printf("i = %d\n", i);
741     assert(i == 64);
742 }
743 
744 /**************************************/
745 
746 class A12
747 {
opIndex(int i1,int i2)748     int opIndex(int i1, int i2) { return i1 * 10 + i2; }
opIndexAssign(int value,int i1,int i2)749     int opIndexAssign(int value, int i1, int i2) { return value * 100 + i1 * 10 + i2; }
750 }
751 
752 
test12()753 void test12()
754 {
755    A12 a = new A12();
756    int i;
757 
758    printf("%d\n", a[1, 2]);
759    assert(a[1, 2] == 12);
760 
761    i = (a[3, 4] = 5);
762    printf("%d\n", i);
763    assert(i == 534);
764 }
765 
766 /**************************************/
767 
768 class A13
769 {
opShl(int x)770  A13 opShl(int x)
771  {
772     printf("A::opShl(int %d)\n", x);
773     printf("%d",x);
774     return this;
775  }
opShl(string x)776  A13 opShl(string x)
777  {
778     printf("A::opShl(char[])\n");
779     printf("%.*s", x.length, x.ptr);
780     return this;
781  }
782 }
783 
784 class B13
785 {
opShl_r(A13 a)786  A13 opShl_r(A13 a)
787  {
788     printf("B::opShl_r(A)\n");
789     return a;
790  }
791 }
792 
test13()793 void test13()
794 {
795     A13 a = new A13();
796     a << 4 << " " << 12 << "\n";
797 
798     B13 b = new B13();
799     a << b;
800 }
801 
802 
803 /**************************************/
804 
805 class Foo14
806 {   int a;
807 
opIn(int x)808     int opIn(int x)
809     {
810         return a + x;
811     }
812 }
813 
test14()814 void test14()
815 {
816     auto f = new Foo14;
817     f.a = 3;
818     auto i = f in 7;
819     assert(i == 10);
820 }
821 
822 /**************************************/
823 
824 // 3983
825 
826 struct Fug
827 {
opEqualsFug828     bool opEquals(ref const Fug y) const {
829         return false;
830     }
831 }
832 
833 struct Fig
834 {
835    Fug f;
836    bool opEquals(Tdummy=void)(ref const Fig y) const {
837       return false;
838    }
839 
840    bool opEquals(T: int)(T y) const {
841       return false;
842    }
843 }
844 
test15()845 void test15()
846 {
847   Fig fx, fy;
848   if (fx==2) {}
849 }
850 
851 /**************************************/
852 // 4953
853 
854 struct S4953a
855 {
856     short _x;
857     bool opBinaryRight(string op)(short x) if (op == "in")
858     {
859         return x == _x;
860     }
861 }
test4953a()862 void test4953a()
863 {
864     S4953a s;
865     5 in s;
866 }
867 
868 struct S4953b
869 {
opBinaryS4953b870     void opBinary(string op)(short x)
871     {}
872 }
test4953b()873 void test4953b()
874 {
875     S4953b s;
876     s + 5;
877 }
878 
879 
880 struct S4953c
881 {
funOpAssignS4953c882     void funOpAssign(float[1u] data) { }
883     void opOpAssign(string op)(float[1u] data) if(op=="<<") { }
884 }
test4953c()885 void test4953c()
886 {
887     // dmd v2.054, v2.055
888     S4953c s;
889     float[1u] a = [1.0f]; // OK: Implicit cast from float[] compiles
890     s.funOpAssign([1.0f]); // OK: Implicit cast from float[] compiles
891     s <<= [1.0f]; // Issue: Implicit cast from float[] does not compile
892     s <<= cast(float[1u])[1.0f]; // OK: Explicit cast from float[] compiles
893 }
894 
f4953d1(dstring d)895 void f4953d1  (dstring d) { dstring e = d; }
f4953d2()896 void f4953d2()(dstring d) { dstring e = d; }
f4953d3(byte[]b)897 void f4953d3  ( byte[] b) { byte[] c = b; }
f4953d4()898 void f4953d4()( byte[] b) { byte[] c = b; }
test4953d()899 void test4953d()
900 {
901     f4953d1("abc");  // OK
902     f4953d2("abc");  // OK
903     f4953d3([1,2,3]); // OK
904     f4953d4([1,2,3]);
905     // Error: template test2.f() does not match any function template declaration
906     // Error: template test2.f() cannot deduce template function from argument types !()(int[])
907 }
908 
909 /**************************************/
910 // 4993
911 
912 // reduced from the bug report
913 struct Bar4993
914 {
opIndexAssignBar4993915     void opIndexAssign(int value, size_t index) {}
916 }
bar4993()917 @property auto bar4993()
918 {
919     return Bar4993();
920 }
test4993()921 void test4993()
922 {
923     bar4993[3] = 42;
924 }
925 
926 /**************************************/
927 // 8133
928 
test8133()929 void test8133()
930 {
931     struct S
932     {
933         int opCall() { return 1; }
934     }
935     struct A
936     {
937         S s;
938         alias s this;
939     }
940     A f = A();
941     assert(f() == 1);
942 }
943 
944 /**************************************/
945 // 8522
946 
947 struct Point8522
948 {
opEqualsPoint8522949     bool opEquals(R)(R rhs) { return true; }
opEqualsPoint8522950     bool opEquals(R)(R rhs) const { return true; }
951 }
952 
test8522()953 void test8522()
954 {
955     Point8522 mp;
956     const Point8522 cp;
957     assert(mp == mp);
958     assert(mp == cp);
959     assert(cp == mp);   // doesn't work
960     assert(cp == cp);   // doesn't work
961 }
962 
963 /**************************************/
964 // 12778
965 
966 struct Vec12778X
967 {
968     Vec12778X opBinary(string op)(Vec12778X b) const
969     if (op == "+")
970     {
971         mixin("return Vec12778X(this.x " ~ op ~ " b.x, this.y " ~ op ~ " b.y);");
972     }
973     alias opBinaryRight = opBinary;
974 
975     float x = 0, y = 0;
976 }
977 
978 struct Vec12778Y
979 {
opAdd()980     Vec12778Y opAdd()(Vec12778Y b) const
981     {
982         enum op = "+";
983         mixin("return Vec12778Y(this.x " ~ op ~ " b.x, this.y " ~ op ~ " b.y);");
984     }
985     alias opAdd_r = opAdd;
986 
987     float x = 0, y = 0;
988 }
989 
test12778()990 void test12778()
991 {
992     struct S
993     {
994         void test1()
995         {
996             Vec12778X vx = vx1 + vx2;   // ok
997             Vec12778Y vy = vy1 + vy2;   // ok
998         }
999 
1000         void test2() const
1001         {
1002             Vec12778X vx = vx1 + vx2;   // ok <- error
1003             Vec12778Y vy = vy1 + vy2;   // ok <- error
1004         }
1005 
1006         Vec12778X vx1, vx2;
1007         Vec12778Y vy1, vy2;
1008     }
1009 }
1010 
1011 /**************************************/
1012 // 14343
1013 
1014 struct S14343a
1015 {
1016     int i;
1017     immutable(Object) o;
1018 
1019     S14343a opUnary(string op)() { return this; }
1020     void opAssign(S14343a other) {}
1021 }
1022 
1023 struct S14343b
1024 {
1025     int i;
1026     immutable(Object) o;
1027 
1028     void opAddAssign(int j) { i += j; }
1029     S14343b opPostInc() { ++i; return this; }
1030     void opAssign(S14343b other) {}
1031 }
1032 
1033 void test14343()
1034 {
1035     {
1036         S14343a s, t;
1037 
1038         t = s;  // OK
1039         ++s;    // OK
1040         s++;    // OK <- Error: cannot modify struct s S with immutable members
1041     }
1042     {
1043         S14343b s;
1044         ++s;
1045         assert(s.i == 1);
1046         s++;
1047         assert(s.i == 2);
1048     }
1049 }
1050 
1051 /**************************************/
1052 // 14344
1053 
1054 struct S14344
1055 {
1056     S14344 opBinary(string op)(S14344 v)
1057     {
1058         static assert(0);
1059     }
1060     S14344 opAssign()(S14344 v)
1061     {
1062         static assert(0);
1063     }
1064 }
1065 
1066 struct S14344Mix
1067 {
1068     S14344 s;
1069     alias s this;
1070 }
1071 
1072 class C14344
1073 {
1074     S14344Mix height() { return S14344Mix(); }
1075 
1076     void update()
1077     {
1078         S14344 height = this.height;
1079     }
1080 }
1081 
1082 /**************************************/
1083 
1084 int main()
1085 {
1086     test1();
1087     test2();
1088     test3();
1089     test4();
1090     test5();
1091     test6();
1092     test7();
1093     test8();
1094     test9();
1095     test10();
1096     test11();
1097     test12();
1098     test13();
1099     test14();
1100     test15();
1101     test4953a();
1102     test4953b();
1103     test4953c();
1104     test4953d();
1105     test4993();
1106     test8133();
1107     test8522();
1108 
1109     printf("Success\n");
1110     return 0;
1111 }
1112