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