1
2 /******************************************/
3 // 3449
4
TypeTuple(T...)5 template TypeTuple(T...) { alias TypeTuple = T; }
6
7 // If module variable has no explicit initializer,
8 // constant folding is not allowed for that.
9 int mg1;
10 const int cg1;
11 immutable int ig1;
this()12 static this()
13 {
14 mg1 = 10;
15 cg1 = 10;
16 ig1 = 10;
17 }
18 static assert(!__traits(compiles, { static assert(mg1 == 0); }));
19 static assert(!__traits(compiles, { static assert(cg1 == 0); }));
20 static assert(!__traits(compiles, { static assert(ig1 == 0); }));
21
22 // But, if module variable has explicit initializer and
23 // non-mutable type, constant folding is allowed for that..
24 int mg2 = 1;
25 const int cg2 = 1;
26 immutable int ig2 = 1;
this()27 static this()
28 {
29 mg2 = 11;
30 static assert(!__traits(compiles, cg2 = 11)); // not allowed for constant folding
31 static assert(!__traits(compiles, ig2 = 11)); // not allowed for constant folding
32 }
33 static assert(!__traits(compiles, { static assert(mg2 == 1); }));
34 static assert(cg2 == 1); // possible
35 static assert(ig2 == 1); // possible
36
37 // For aggregate fields, compiler behavior will be changed.
test3449()38 void test3449()
39 {
40 static struct S(T)
41 {
42 T field1; // doesn't have explicit initializer
43 T field2 = 1; // has explicit initializer
44
45 this(int n)
46 {
47 field1 = n; // allowed
48 field2 = n; // NEW! re-assigning during construction is allowed for any qualified fields.
49 }
50 }
51
52 foreach (T; TypeTuple!(int, const int, immutable int))
53 {
54 alias S!T ST;
55
56 auto s1 = ST(); // default construction
57 assert(s1.field1 == 0); // == T.init
58 assert(s1.field2 == 1); // == specified initializer
59
60 // Getting address for non-mutable field is allowed.
61 T* s1p1 = &s1.field1;
62 T* s1p2 = &s1.field2;
63 assert(*s1p1 == 0);
64 assert(*s1p2 == 1);
65 static if (is(T == int))
66 { // If T is mutable,
67 // modification through indirection is allowed
68 *s1p1 = 100, *s1p2 = 101;
69 assert(*s1p1 == 100);
70 assert(*s1p2 == 101);
71 }
72 else
73 { // If T is not mutable, modification is not allowed
74 static assert(!__traits(compiles, *s1p1 = 100));
75 static assert(!__traits(compiles, *s1p2 = 100));
76 }
77
78 // Access to non-static non-mutable field is
79 // now correctly rejected by "need this" error.
80 static assert(!__traits(compiles, ST.field1 == 1));
81 static assert(!__traits(compiles, ST.field2 == 0));
82
83 // So, re-assignment of non-mutable fields
84 // during construction is enough acceptable.
85 auto s2 = ST(10);
86 assert(s2.field1 == 10);
87 assert(s2.field2 == 10);
88 }
89 }
90
91 /******************************************/
92 // 10643
93
94 struct S10643
95 {
96 const int[1000] x = void;
97
thisS1064398 this(int n)
99 {
100 x[] = n;
101 }
102 }
103 static assert(S10643.sizeof == int.sizeof * 1000);
104
105 /******************************************/
106
main()107 int main()
108 {
109 test3449();
110
111 return 0;
112 }
113