1 import core.stdc.stdio;
2 
TypeTuple(T...)3 template TypeTuple(T...){ alias T TypeTuple; }
4 
5 /***************************************************/
6 // 2625
7 
8 struct Pair {
9     immutable uint g1;
10     uint g2;
11 }
12 
test1()13 void test1() {
14     Pair[1] stuff;
15     static assert(!__traits(compiles, (stuff[0] = Pair(1, 2))));
16 }
17 
18 /***************************************************/
19 // 5327
20 
21 struct ID
22 {
23     immutable int value;
24 }
25 
26 struct Data
27 {
28     ID id;
29 }
test2()30 void test2()
31 {
32     Data data = Data(ID(1));
33     immutable int* val = &data.id.value;
34     static assert(!__traits(compiles, data = Data(ID(2))));
35 }
36 
37 /***************************************************/
38 
39 struct S31A
40 {
41     union
42     {
43         immutable int field1;
44         immutable int field2;
45     }
46 
47     enum result = false;
48 }
49 struct S31B
50 {
51     union
52     {
53         immutable int field1;
54         int field2;
55     }
56 
57     enum result = true;
58 }
59 struct S31C
60 {
61     union
62     {
63         int field1;
64         immutable int field2;
65     }
66 
67     enum result = true;
68 }
69 struct S31D
70 {
71     union
72     {
73         int field1;
74         int field2;
75     }
76 
77     enum result = true;
78 }
79 
80 struct S32A
81 {
82     int dummy0;
83     union
84     {
85         immutable int field1;
86         int field2;
87     }
88 
89     enum result = true;
90 }
91 struct S32B
92 {
93     immutable int dummy0;
94     union
95     {
96         immutable int field1;
97         int field2;
98     }
99 
100     enum result = false;
101 }
102 
103 
104 struct S32C
105 {
106     union
107     {
108         immutable int field1;
109         int field2;
110     }
111     int dummy1;
112 
113     enum result = true;
114 }
115 struct S32D
116 {
117     union
118     {
119         immutable int field1;
120         int field2;
121     }
122     immutable int dummy1;
123 
124     enum result = false;
125 }
126 
test3()127 void test3()
128 {
129     foreach (S; TypeTuple!(S31A,S31B,S31C,S31D, S32A,S32B,S32C,S32D))
130     {
131         S s;
132         static assert(__traits(compiles, s = s) == S.result);
133     }
134 }
135 
136 /***************************************************/
137 // 3511
138 
139 struct S4
140 {
141     private int _prop = 42;
propertyS4142     ref int property() { return _prop; }
143 }
144 
test4()145 void test4()
146 {
147     S4 s;
148     assert(s.property == 42);
149     s.property = 23;    // Rewrite to s.property() = 23
150     assert(s.property == 23);
151 }
152 
153 /***************************************************/
154 
155 struct S5
156 {
157     int mX;
158     string mY;
159 
xS5160     ref int x()
161     {
162         return mX;
163     }
yS5164     ref string y()
165     {
166         return mY;
167     }
168 
errS5169     ref int err(Object)
170     {
171         static int v;
172         return v;
173     }
174 }
175 
test5()176 void test5()
177 {
178     S5 s;
179     s.x += 4;
180     assert(s.mX == 4);
181     s.x -= 2;
182     assert(s.mX == 2);
183     s.x *= 4;
184     assert(s.mX == 8);
185     s.x /= 2;
186     assert(s.mX == 4);
187     s.x %= 3;
188     assert(s.mX == 1);
189     s.x <<= 3;
190     assert(s.mX == 8);
191     s.x >>= 1;
192     assert(s.mX == 4);
193     s.x >>>= 1;
194     assert(s.mX == 2);
195     s.x &= 0xF;
196     assert(s.mX == 0x2);
197     s.x |= 0x8;
198     assert(s.mX == 0xA);
199     s.x ^= 0xF;
200     assert(s.mX == 0x5);
201 
202     s.x ^^= 2;
203     assert(s.mX == 25);
204 
205     s.mY = "ABC";
206     s.y ~= "def";
207     assert(s.mY == "ABCdef");
208 
209     static assert(!__traits(compiles, s.err += 1));
210 }
211 
212 /***************************************************/
213 // 4424
214 
test4424()215 void test4424()
216 {
217     static struct S
218     {
219         this(this) {}
220         void opAssign(T)(T rhs) if (!is(T == S)) {}
221     }
222 }
223 
224 /***************************************************/
225 // 6174
226 
227 struct CtorTest6174(Data)
228 {
229     const Data data;
230 
231     const Data[2] sa1;
232     const Data[2][1] sa2;
233     const Data[][2] sa3;
234 
235     const Data[] da1;
236     const Data[2][] da2;
237 
238     this(Data a)
239     {
240         auto pdata = &data;
241 
242         // If compiler can determine that an assignment really sets the fields
243         // which belongs to `this` object, it can bypass const qualifier.
244         // For example, sa3, da1, da2, and pdata have indirections.
245         // As long as you don't try to rewrite values beyond the indirections,
246         // an assignment will always be succeeded inside constructor.
247 
248         static assert( is(typeof( data        = a         )));    // OK
249       static if (is(Data == struct))
250       {
251         static assert( is(typeof( data.x      = 1         )));    // OK
252         static assert( is(typeof( data.y      = 2         )));    // OK
253       }
254         static assert(!is(typeof( *pdata      = a         )));    // NG
255         static assert( is(typeof( *&data      = a         )));    // OK
256 
257         static assert( is(typeof( sa1         = [a,a]     )));    // OK
258         static assert( is(typeof( sa1[0]      = a         )));    // OK
259         static assert( is(typeof( sa1[]       = a         )));    // OK
260         static assert( is(typeof( sa1[][]     = a         )));    // OK
261 
262         static assert( is(typeof( sa2         = [[a,a]]   )));    // OK
263         static assert( is(typeof( sa2[0][0]   = a         )));    // OK
264         static assert( is(typeof( sa2[][0][]  = a         )));    // OK
265         static assert( is(typeof( sa2[0][][0] = a         )));    // OK
266 
267         static assert( is(typeof( sa3         = [[a],[]]  )));    // OK
268         static assert( is(typeof( sa3[0]      = [a,a]     )));    // OK
269         static assert(!is(typeof( sa3[0][0]   = a         )));    // NG
270         static assert( is(typeof( sa3[]       = [a]       )));    // OK
271         static assert( is(typeof( sa3[][0]    = [a]       )));    // OK
272         static assert(!is(typeof( sa3[][0][0] = a         )));    // NG
273 
274         static assert( is(typeof( da1         = [a,a]     )));    // OK
275         static assert(!is(typeof( da1[0]      = a         )));    // NG
276         static assert(!is(typeof( da1[]       = a         )));    // NG
277 
278         static assert( is(typeof( da2         = [[a,a]]   )));    // OK
279         static assert(!is(typeof( da2[0][0]   = a         )));    // NG
280         static assert(!is(typeof( da2[]       = [a,a]     )));    // NG
281         static assert(!is(typeof( da2[][0]    = a         )));    // NG
282         static assert(!is(typeof( da2[0][]    = a         )));    // NG
283     }
284     void func(Data a)
285     {
286         auto pdata = &data;
287 
288         static assert(!is(typeof( data        = a         )));    // NG
289       static if (is(Data == struct))
290       {
291         static assert(!is(typeof( data.x      = 1         )));    // NG
292         static assert(!is(typeof( data.y      = 2         )));    // NG
293       }
294         static assert(!is(typeof( *pdata      = a         )));    // NG
295         static assert(!is(typeof( *&data      = a         )));    // NG
296 
297         static assert(!is(typeof( sa1         = [a,a]     )));    // NG
298         static assert(!is(typeof( sa1[0]      = a         )));    // NG
299         static assert(!is(typeof( sa1[]       = a         )));    // NG
300         static assert(!is(typeof( sa1[][]     = a         )));    // NG
301 
302         static assert(!is(typeof( sa2         = [[a,a]]   )));    // NG
303         static assert(!is(typeof( sa2[0][0]   = a         )));    // NG
304         static assert(!is(typeof( sa2[][0][]  = a         )));    // NG
305         static assert(!is(typeof( sa2[0][][0] = a         )));    // NG
306 
307         static assert(!is(typeof( sa3         = [[a],[]]  )));    // NG
308         static assert(!is(typeof( sa3[0]      = [a,a]     )));    // NG
309         static assert(!is(typeof( sa3[0][0]   = a         )));    // NG
310         static assert(!is(typeof( sa3[]       = [a]       )));    // NG
311         static assert(!is(typeof( sa3[][0]    = [a]       )));    // NG
312         static assert(!is(typeof( sa3[][0][0] = a         )));    // NG
313 
314         static assert(!is(typeof( da1         = [a,a]     )));    // NG
315         static assert(!is(typeof( da1[0]      = a         )));    // NG
316         static assert(!is(typeof( da1[]       = a         )));    // NG
317 
318         static assert(!is(typeof( da2         = [[a,a]]   )));    // NG
319         static assert(!is(typeof( da2[0][0]   = a         )));    // NG
320         static assert(!is(typeof( da2[]       = [a,a]     )));    // NG
321         static assert(!is(typeof( da2[][0]    = a         )));    // NG
322         static assert(!is(typeof( da2[0][]    = a         )));    // NG
323     }
324 }
325 
326 const char gc6174;
327 const char[1] ga6174;
328 static this()
329 {
330     gc6174 = 'a';    // OK
331     ga6174[0] = 'a'; // line 5, Err
332 }
333 struct Foo6174
334 {
335     const char cc;
336     const char[1] array;
337     const char[1] arr;
338     this(char c)
339     {
340         cc = c;       // OK
341         array = [c];  // line 12, Err
342         arr[0] = c;   // line 12, Err
343     }
344 }
345 void test6174a()
346 {
347     static struct Pair
348     {
349         const int x;
350         int y;
351     }
352     alias CtorTest6174!long CtorTest1;
353     alias CtorTest6174!Pair CtorTest2;
354 
355     auto foo = Foo6174('c');
356 }
357 
358 /***************************************************/
359 
360 template Select(bool cond, T, F)
361 {
362     static if (cond)
363         alias Select = T;
364     else
365         alias Select = F;
366 }
367 
368 void test6174b()
369 {
370     enum { none, unrelated, mutable, constant }
371 
372     static struct FieldStruct(bool c, int k)
373     {
374         enum fieldConst = c;
375         enum assignKind = k;
376 
377         Select!(fieldConst, const int, int) x;
378         int y;
379 
380         static if (assignKind == none)      {}
381         static if (assignKind == unrelated) void opAssign(int) {}
382         static if (assignKind == mutable)   void opAssign(FieldStruct) {}
383         static if (assignKind == constant)  void opAssign(FieldStruct) const {}
384     }
385     static struct TestStruct(F, bool fieldConst)
386     {
387         int w;
388         Select!(fieldConst, const F, F) f;
389         Select!(fieldConst, const int, int) z;
390 
391         this(int)
392         {
393             // If F has an identity `opAssign`,it is used even for initializing.
394             // Otherwise, initializing  will always succeed, by bypassing const qualifier.
395             static assert(is(typeof( f = F() )) == (
396                             F.assignKind == none ||
397                             F.assignKind == unrelated ||
398                             F.assignKind == mutable ||
399                             F.assignKind == constant));
400 
401             static assert(is(typeof(   w = 1000 )) == true);
402             static assert(is(typeof( f.x = 1000 )) == true);
403             static assert(is(typeof( f.y = 1000 )) == true);
404             static assert(is(typeof(   z = 1000 )) == true);
405         }
406         void func()
407         {
408             // In mutable member functions, identity assignment is allowed
409             // when all of the fields are identity assignable,
410             // or identity `opAssign`, which callable from mutable object, is defined.
411             static assert(__traits(compiles, f = F()) == (
412                             F.assignKind == none      && !fieldConst && !F.fieldConst ||
413                             F.assignKind == unrelated && !fieldConst && !F.fieldConst ||
414                             F.assignKind == constant ||
415                             F.assignKind == mutable   && !fieldConst));
416 
417             static assert(__traits(compiles,   w = 1000) == true);
418             static assert(__traits(compiles, f.x = 1000) == (!fieldConst && !F.fieldConst));
419             static assert(__traits(compiles, f.y = 1000) == (!fieldConst && true         ));
420             static assert(__traits(compiles,   z = 1000) == !fieldConst);
421         }
422         void func() const
423         {
424             // In non-mutable member functions, identity assignment is allowed
425             // just only user-defined identity `opAssign` is qualified.
426             static assert(__traits(compiles, f = F()) == (F.assignKind == constant));
427 
428             static assert(__traits(compiles,   w = 1000) == false);
429             static assert(__traits(compiles, f.x = 1000) == false);
430             static assert(__traits(compiles, f.y = 1000) == false);
431             static assert(__traits(compiles,   z = 1000) == false);
432         }
433     }
434     foreach (fieldConst; TypeTuple!(false, true))
435     foreach (  hasConst; TypeTuple!(false, true))
436     foreach (assignKind; TypeTuple!(none, unrelated, mutable, constant))
437     {
438         alias TestStruct!(FieldStruct!(hasConst, assignKind), fieldConst) TestX;
439     }
440 }
441 
442 void test6174c()
443 {
444     static assert(!is(typeof({
445         int func1a(int n)
446         in{ n = 10; }
447         body { return n; }
448     })));
449     static assert(!is(typeof({
450         int func1b(int n)
451         out(r){ r = 20; }
452         body{ return n; }
453     })));
454 
455     struct DataX
456     {
457         int x;
458     }
459     static assert(!is(typeof({
460         DataX func2a(DataX n)
461         in{ n.x = 10; }
462         body { return n; }
463     })));
464     static assert(!is(typeof({
465         DataX func2b(DataX n)
466         in{}
467         out(r){ r.x = 20; }
468         body{ return n; }
469     })));
470 }
471 
472 /***************************************************/
473 // 6216
474 
475 void test6216a()
476 {
477     static class C{}
478 
479     static struct Xa{ int n; }
480     static struct Xb{ int[] a; }
481     static struct Xc{ C c; }
482     static struct Xd{ void opAssign(typeof(this) rhs){} }
483     static struct Xe{ void opAssign(T)(T rhs){} }
484     static struct Xf{ void opAssign(int rhs){} }
485     static struct Xg{ void opAssign(T)(T rhs)if(!is(T==typeof(this))){} }
486 
487     // has value type as member
488     static struct S1 (X){ static if (!is(X==void)) X x; int n; }
489 
490     // has reference type as member
491     static struct S2a(X){ static if (!is(X==void)) X x; int[] a; }
492     static struct S2b(X){ static if (!is(X==void)) X x; C c; }
493 
494     // has identity opAssign
495     static struct S3a(X){ static if (!is(X==void)) X x; void opAssign(typeof(this) rhs){} }
496     static struct S3b(X){ static if (!is(X==void)) X x; void opAssign(T)(T rhs){} }
497 
498     // has non identity opAssign
499     static struct S4a(X){ static if (!is(X==void)) X x; void opAssign(int rhs){} }
500     static struct S4b(X){ static if (!is(X==void)) X x; void opAssign(T)(T rhs)if(!is(T==typeof(this))){} }
501 
502     enum result = [
503         /*S1,   S2a,    S2b,    S3a,    S3b,    S4a,    S4b*/
504 /*- */  [true,  true,   true,   true,   true,   true,   true],
505 /*Xa*/  [true,  true,   true,   true,   true,   true,   true],
506 /*Xb*/  [true,  true,   true,   true,   true,   true,   true],
507 /*Xc*/  [true,  true,   true,   true,   true,   true,   true],
508 /*Xd*/  [true,  true,   true,   true,   true,   true,   true],
509 /*Xe*/  [true,  true,   true,   true,   true,   true,   true],
510 /*Xf*/  [true,  true,   true,   true,   true,   true,   true],
511 /*Xg*/  [true,  true,   true,   true,   true,   true,   true],
512     ];
513 
514     pragma(msg, "\\\tS1\tS2a\tS2b\tS3a\tS3b\tS4a\tS4b");
515     foreach (i, X; TypeTuple!(void,Xa,Xb,Xc,Xd,Xe,Xf,Xg))
516     {
517         S1!X  s1;
518         S2a!X s2a;
519         S2b!X s2b;
520         S3a!X s3a;
521         S3b!X s3b;
522         S4a!X s4a;
523         S4b!X s4b;
524 
525         pragma(msg,
526                 is(X==void) ? "-" : X.stringof,
527                 "\t", __traits(compiles, (s1  = s1)),
528                 "\t", __traits(compiles, (s2a = s2a)),
529                 "\t", __traits(compiles, (s2b = s2b)),
530                 "\t", __traits(compiles, (s3a = s3a)),
531                 "\t", __traits(compiles, (s3b = s3b)),
532                 "\t", __traits(compiles, (s4a = s4a)),
533                 "\t", __traits(compiles, (s4b = s4b))  );
534 
535         static assert(result[i] ==
536             [   __traits(compiles, (s1  = s1)),
537                 __traits(compiles, (s2a = s2a)),
538                 __traits(compiles, (s2b = s2b)),
539                 __traits(compiles, (s3a = s3a)),
540                 __traits(compiles, (s3b = s3b)),
541                 __traits(compiles, (s4a = s4a)),
542                 __traits(compiles, (s4b = s4b))  ]);
543     }
544 }
545 
546 void test6216b()
547 {
548     static int cnt = 0;
549 
550     static struct X
551     {
552         int n;
553         void opAssign(X rhs){ cnt = 1; }
554     }
555     static struct S
556     {
557         int n;
558         X x;
559     }
560 
561     S s;
562     s = s;
563     assert(cnt == 1);
564     // Built-in opAssign runs member's opAssign
565 }
566 
567 void test6216c()
568 {
569     static int cnt = 0;
570 
571     static struct X
572     {
573         int n;
574         void opAssign(const X rhs) const { cnt = 2; }
575     }
576     static struct S
577     {
578         int n;
579         const(X) x;
580     }
581 
582     S s;
583     const(S) cs;
584     s = s;
585     s = cs;     // cs is copied as mutable and assigned into s
586     assert(cnt == 2);
587     static assert(!__traits(compiles, cs = cs));
588                 // built-in opAssin is only allowed with mutable object
589 }
590 
591 void test6216d()
592 {
593     static int cnt = 0;
594 
595     static struct X
596     {
597         int[] arr;  // X has mutable indirection
598         void opAssign(const X rhs) const { ++cnt; }
599     }
600     static struct S
601     {
602         int n;
603         const(X) x;
604     }
605 
606     X mx;
607     const X cx;
608     mx = mx;    // copying mx to const X is possible
609     assert(cnt == 1);
610     mx = cx;
611     assert(cnt == 2);
612     cx = mx;    // copying mx to const X is possible
613     assert(cnt == 3);
614 
615     S s;
616     const(S) cs;
617     s = s;
618     s = cs;
619     //assert(cnt == 4);
620     static assert(!__traits(compiles, cs = cs));
621                 // built-in opAssin is only allowed with mutable object
622 }
623 
624 void test6216e()
625 {
626     static struct X
627     {
628         int x;
629         @disable void opAssign(X);
630     }
631     static struct S
632     {
633         X x;
634     }
635     S s;
636     static assert(!__traits(compiles, s = s));
637                 // built-in generated opAssin is marked as @disable.
638 }
639 
640 /***************************************************/
641 // 6286
642 
643 void test6286()
644 {
645     const(int)[4] src = [1, 2, 3, 4];
646     int[4] dst;
647     dst = src;
648     dst[] = src[];
649     dst = 4;
650     int[4][4] x;
651     x = dst;
652 }
653 
654 /***************************************************/
655 // 6336
656 
657 void test6336()
658 {
659     // structs aren't identity assignable
660     static struct S1
661     {
662         immutable int n;
663     }
664     static struct S2
665     {
666         void opAssign(int n){ assert(0); }
667     }
668 
669     S1 s1;
670     S2 s2;
671 
672     void f(S)(out S s){}
673     static assert(!__traits(compiles, f(s1)));
674     f(s2);
675     // Out parameters refuse only S1 because it isn't blit assignable
676 
677     ref S g(S)(ref S s){ return s; }
678     g(s1);
679     g(s2);
680     // Allow return by ref both S1 and S2
681 }
682 
683 /***************************************************/
684 // 8783
685 
686 struct Foo8783
687 {
688     int[1] bar;
689 }
690 
691 const Foo8783[1] foos8783;
692 
693 static this()
694 {
695     foreach (i; 0 .. foos8783.length)
696         foos8783[i].bar[i] = 1; // OK
697     foreach (i, ref f; foos8783)
698         f.bar[i] = 1; // line 9, Error
699 }
700 
701 /***************************************************/
702 // 9077
703 
704 struct S9077a
705 {
706     void opAssign(int n) {}
707     void test() { typeof(this) s; s = this; }
708     this(this) {}
709 }
710 struct S9077b
711 {
712     void opAssign()(int n) {}
713     void test() { typeof(this) s; s = this; }
714     this(this) {}
715 }
716 
717 /***************************************************/
718 // 9140
719 
720 immutable(int)[] bar9140()
721 out(result) {
722     foreach (ref r; result) {}
723 } body {
724     return null;
725 }
726 
727 /***************************************************/
728 // 9154
729 
730 struct S9154a
731 {
732     int x;
733     void opAssign(ref S9154a s) { }
734 }
735 struct S9154b
736 {
737     int x;
738     void opAssign(X)(ref X s) { }
739 }
740 struct T9154
741 {
742     S9154a member1;
743     S9154b member2;
744 }
745 
746 void test9154()
747 {
748     T9154 t1, t2;
749     t1 = t2;
750 }
751 
752 /***************************************************/
753 // 9258
754 
755 class A9258 {}
756 class B9258 : A9258 // Error: class test.B9258 identity assignment operator overload is illegal
757 {
758     void opAssign(A9258 b) {}
759 }
760 
761 class C9258
762 {
763     int n;
764     alias n this;
765     void opAssign(int n) {}
766 }
767 class D9258
768 {
769     int n;
770     alias n this;
771     void opAssign(int n, int y = 0) {}
772 }
773 class E9258 : A9258
774 {
775     void set(A9258 a) {}
776     alias set opAssign;
777 }
778 
779 /***************************************************/
780 // 9416
781 
782 struct S9416
783 {
784     void opAssign()(S9416)
785     {
786         static assert(0);
787     }
788 }
789 struct U9416
790 {
791     S9416 s;
792 }
793 void test9416()
794 {
795     U9416 u;
796     static assert(__traits(allMembers, U9416)[$-1] == "opAssign");
797     static assert(!__traits(compiles, u = u));
798 }
799 
800 /***************************************************/
801 // 9658
802 
803 struct S9658
804 {
805     private bool _isNull = true;
806     this(int v) const
807     {
808         _isNull = false;    // cannot modify const expression this._isNull
809     }
810 }
811 
812 /***************************************************/
813 // 11187
814 
815 void test11187()
816 {
817     static struct X
818     {
819         int[] arr;
820     }
821     static struct S
822     {
823         const(X) cx;
824     }
825     static assert(is(typeof((const S).init.cx.arr) == const(int[])));
826     static assert(is(typeof((      S).init.cx.arr) == const(int[])));
827     const S sc;
828     S sm = sc;
829     static assert(is(const S : S));
830 }
831 
832 /***************************************************/
833 // 12131
834 
835 struct X12131
836 {
837     void opAssign()(X12131 y) pure {}
838 }
839 
840 struct Y12131
841 {
842     X12131 a;
843 }
844 
845 void test12131() pure
846 {
847     X12131 x;
848     x = X12131();   // OK
849 
850     Y12131 y;
851     y = Y12131();   // OK <- Error
852 }
853 
854 /***************************************************/
855 // 12211
856 
857 void test12211()
858 {
859     int a = 0;
860     void foo(ref int x)
861     {
862         assert(x == 10);
863         assert(&x == &a);
864         x = 3;
865     }
866     foo(a = 10);
867     assert(a == 3);
868     foo(a += 7);
869     assert(a == 3);
870 
871     // array ops should make rvalue
872     int[3] sa, sb;
873     void bar(ref int[]) {}
874     static assert(!__traits(compiles, bar(sa[]  = sb[])));
875     static assert(!__traits(compiles, bar(sa[] += sb[])));
876 }
877 
878 /***************************************************/
879 // 4791 (dup of 12212)
880 
881 void test4791()
882 {
883     int[2] na;
884     na = na;
885 
886     static struct S
887     {
888         static string res;
889         int n;
890         this(this) { ++n; res ~= "p" ~ cast(char)('0' + n); }
891         ~this()    {      res ~= "d" ~ cast(char)('0' + n); }
892     }
893     {
894         S[3] sa;
895         sa[0].n = 1, sa[1].n = 2, sa[2].n = 3;
896 
897         S.res = null;
898         sa = sa;
899         assert(S.res == "p2d1p3d2p4d3");
900         assert(sa[0].n == 2 && sa[1].n == 3 && sa[2].n == 4);
901 
902         S.res = null;
903     }
904     assert(S.res == "d4d3d2");
905 }
906 
907 /***************************************************/
908 // 12212
909 
910 void test12212()
911 {
912     struct S
913     {
914         int x, y;
915         static int cpctor;
916         this(this) { cpctor++; }
917     }
918 
919     void funcVal(E)(E[3] x) {}
920     auto funcRef(E)(ref E[3] x) { return &x; }
921     ref get(E)(ref E[3] a){ return a; }
922 
923     {
924         int[3] a, b;
925         funcVal(a = b);
926 
927         auto p = funcRef(a = b);
928         assert(p == &a);
929     }
930 
931     {
932         S.cpctor = 0;
933 
934         S[3] a, b;
935         assert(S.cpctor == 0);
936 
937         S[3] c = a;
938         //printf("cpctpr = %d\n", S.cpctor);
939         assert(S.cpctor == 3);
940         S.cpctor = 0;
941 
942         c = a;
943         //printf("cpctpr = %d\n", S.cpctor);
944         assert(S.cpctor == 3);
945         S.cpctor = 0;
946 
947         c = (a = b);
948         //printf("cpctpr = %d\n", S.cpctor);
949         assert(S.cpctor == 6);
950         S.cpctor = 0;
951 
952         c = (get(a) = b);
953         //printf("cpctpr = %d\n", S.cpctor);
954         assert(S.cpctor == 6);
955         S.cpctor = 0;
956     }
957     {
958         S.cpctor = 0;
959 
960         S[3] a, b;
961         assert(S.cpctor == 0);
962 
963         funcVal(a = b);
964         //printf("cpctpr = %d\n", S.cpctor);
965         assert(S.cpctor == 6);
966         S.cpctor = 0;
967 
968         funcVal(get(a) = b);
969         //printf("cpctpr = %d\n", S.cpctor);
970         assert(S.cpctor == 6);
971         S.cpctor = 0;
972     }
973     {
974         S.cpctor = 0;
975 
976         S[3] a, b;
977         assert(S.cpctor == 0);
978 
979         S[3]* p;
980 
981         p = funcRef(a = b);
982         //printf("cpctpr = %d\n", S.cpctor);
983         assert(p == &a);
984         assert(S.cpctor == 3);
985         S.cpctor = 0;
986 
987         p = funcRef(get(a) = b);
988         assert(p == &a);
989         //printf("cpctpr = %d\n", S.cpctor);
990         assert(S.cpctor == 3);
991         S.cpctor = 0;
992     }
993 }
994 
995 /***************************************************/
996 // 12650
997 
998 void test12650()
999 {
1000     // AssignExp::toElem should make an lvalue of e1.
1001     static class A1
1002     {
1003         struct S { int a; }
1004 
1005         static foo(ref const(S) s)
1006         {
1007             assert(s.a == 2);
1008             return &s;
1009         }
1010 
1011         S s;
1012 
1013         this()
1014         {
1015             const v = S(2);
1016 
1017             // (this.s = v) will become ConstructExp
1018             auto p = foo(s = v);
1019             assert(p == &s);
1020         }
1021     }
1022     assert(new A1().s.a == 2);
1023 
1024     static class A2
1025     {
1026         static foo(ref int[2] sa)
1027         {
1028             assert(sa[1] == 2);
1029             return &sa;
1030         }
1031 
1032         int[2] sa;
1033 
1034         this()
1035         {
1036             // (this.sa = [1,2]) will become ConstructExp
1037             auto p = foo(sa = [1,2]);
1038             assert(p == &sa);
1039         }
1040     }
1041     assert(new A2().sa[1] == 2);
1042 
1043     static class A3
1044     {
1045         static foo(ref int n)
1046         {
1047             assert(n == 2);
1048             return &n;
1049         }
1050 
1051         int n;
1052 
1053         this()
1054         {
1055             const v = 2;
1056 
1057             // (this.n = v) will become ConstructExp
1058             auto p = foo(n = v);
1059             assert(p == &n);
1060         }
1061     }
1062     assert(new A3().n == 2);
1063 }
1064 
1065 /***************************************************/
1066 // 13044
1067 
1068 void test13044()
1069 {
1070     static struct Good
1071     {
1072         const int i;
1073     }
1074 
1075     static struct Bad
1076     {
1077         const int i;
1078         ~this() {}
1079     }
1080 
1081     Good good1, good2;
1082     static assert(!__traits(compiles, { good1 = good2; })); // OK
1083 
1084     Bad bad1, bad2;
1085     static assert(!__traits(compiles, { bad1 = bad2; }));   // OK <- fails
1086 }
1087 
1088 /***************************************************/
1089 // 12500
1090 
1091 void test12500()
1092 {
1093     size_t foo;
1094     ++foo *= 1.5;   // Rewrite to: (foo += 1) *= 1.5;
1095 }
1096 
1097 /***************************************************/
1098 // 14672
1099 
1100 void test14672()
1101 {
1102     interface I {}
1103 
1104     class B {}
1105     class D : B, I {}
1106 
1107     D d = new D();
1108     D[] da = [d];
1109     B[] ba = [null];
1110     I[] ia = [null];
1111 
1112     // ba and da points different payloads,
1113     // so element-wise assignment should work.
1114     ba[] = da[];    // OK <- e2ir ICE
1115     assert(ba[0] is d);
1116 
1117     // Today element-wise assignment is implemented as memcpy, For that reason
1118     // the conversion from derived classes to base interfaces is disallowed
1119     // because it requries offset adjustments.
1120     static assert(!__traits(compiles, { ia[] = da[]; }));
1121 
1122     // after the assignment, ba will wongly point the payload of da,
1123     // that's typed as D[]. To aboid type system breaking, it's disallowed.
1124     static assert(!__traits(compiles, { ba = da; }));
1125 
1126     // the assigned array literal is a new payload,
1127     // so rebinding ba should work.
1128     ba = [d];       // OK
1129     assert(ba[0] is d);
1130 }
1131 
1132 /***************************************************/
1133 // 15044
1134 
1135 void destroy15044(T)(ref T obj)
1136 {
1137     static if (__traits(hasMember, T, "__xdtor"))
1138         obj.__xdtor();
1139     else
1140         static assert(0, T.stringof);
1141 }
1142 
1143 struct V15044
1144 {
1145     ~this()
1146     {
1147     }
1148 
1149     RC15044!V15044 dup()
1150     {
1151         return RC15044!V15044(&this);
1152     }
1153 }
1154 
1155 struct RC15044(T)
1156 {
1157     ~this()
1158     {
1159         destroy15044(*t);
1160         static assert(__traits(hasMember, T, "__xdtor"));
1161     }
1162     T* t;
1163 }
1164 
1165 /***************************************************/
1166 
1167 int main()
1168 {
1169     test1();
1170     test2();
1171     test3();
1172     test4();
1173     test5();
1174     test4424();
1175     test6174a();
1176     test6174b();
1177     test6174c();
1178     test6216a();
1179     test6216b();
1180     test6216c();
1181     test6216d();
1182     test6216e();
1183     test6286();
1184     test6336();
1185     test9154();
1186     test9416();
1187     test11187();
1188     test12131();
1189     test12211();
1190     test4791();
1191     test12212();
1192     test12650();
1193     test13044();
1194     test12500();
1195     test14672();
1196 
1197     printf("Success\n");
1198     return 0;
1199 }
1200