1 // PERMUTE_ARGS: -property
2
3 extern (C) int printf(const char* fmt, ...);
4
5 // Is -property option specified?
6 enum enforceProperty = !__traits(compiles, {
7 int prop(){ return 1; }
8 int n = prop;
9 });
10
11 /*******************************************/
12
select(alias v1,alias v2)13 template select(alias v1, alias v2)
14 {
15 static if (enforceProperty)
16 enum select = v1;
17 else
18 enum select = v2;
19 }
20
Test(int N)21 struct Test(int N)
22 {
23 int value;
24 int getset;
25
26 static if (N == 0)
27 {
28 ref foo(){ getset = 1; return value; }
29
30 enum result = select!(0, 1);
31 // -property test.d(xx): Error: not a property foo
32 // (no option) prints "getter"
33 }
34 static if (N == 1)
35 {
36 ref foo(int x){ getset = 2; value = x; return value; }
37
38 enum result = select!(0, 2);
39 // -property test.d(xx): Error: not a property foo
40 // (no option) prints "setter"
41 }
42 static if (N == 2)
43 {
44 @property ref foo(){ getset = 1; return value; }
45
46 enum result = select!(1, 1);
47 // -property prints "getter"
48 // (no option) prints "getter"
49 }
50 static if (N == 3)
51 {
52 @property ref foo(int x){ getset = 2; value = x; return value; }
53
54 enum result = select!(2, 2);
55 // -property prints "setter"
56 // (no option) prints "setter"
57 }
58
59
60 static if (N == 4)
61 {
62 ref foo() { getset = 1; return value; }
63 ref foo(int x){ getset = 2; value = x; return value; }
64
65 enum result = select!(0, 2);
66 // -property test.d(xx): Error: not a property foo
67 // (no option) prints "setter"
68 }
69 static if (N == 5)
70 {
71 @property ref foo() { getset = 1; return value; }
72 ref foo(int x){ getset = 2; value = x; return value; }
73
74 enum result = select!(0, 0);
75 // -property test.d(xx): Error: cannot overload both property and non-property functions
76 // (no option) test.d(xx): Error: cannot overload both property and non-property functions
77 }
78 static if (N == 6)
79 {
80 ref foo() { getset = 1; return value; }
81 @property ref foo(int x){ getset = 2; value = x; return value; }
82
83 enum result = select!(0, 0);
84 // -property test.d(xx): Error: cannot overload both property and non-property functions
85 // (no option) test.d(xx): Error: cannot overload both property and non-property functions
86 }
87 static if (N == 7)
88 {
89 @property ref foo() { getset = 1; return value; }
90 @property ref foo(int x){ getset = 2; value = x; return value; }
91
92 enum result = select!(2, 2);
93 // -property prints "setter"
94 // (no option) prints "setter"
95 }
96 }
97
seq(T...)98 template seq(T...)
99 {
100 alias T seq;
101 }
102 template iota(int begin, int end)
103 if (begin <= end)
104 {
105 static if (begin == end)
106 alias seq!() iota;
107 else
108 alias seq!(begin, iota!(begin+1, end)) iota;
109 }
110
test1()111 void test1()
112 {
113 foreach (N; iota!(0, 8))
114 {
115 printf("%d: ", N);
116
117 Test!N s;
118 static if (Test!N.result == 0)
119 {
120 static assert(!is(typeof({ s.foo = 1; })));
121 printf("compile error\n");
122 }
123 else
124 {
125 s.foo = 1;
126 if (s.getset == 1)
127 printf("getter\n");
128 else
129 printf("setter\n");
130 assert(s.getset == Test!N.result);
131 }
132 }
133 }
134
135 /*******************************************/
136 // 7722
137
138 class Foo7722 {}
spam7722(Foo7722 f)139 void spam7722(Foo7722 f) {}
140
test7722()141 void test7722()
142 {
143 auto f = new Foo7722;
144 static if (enforceProperty)
145 static assert(!__traits(compiles, f.spam7722));
146 else
147 f.spam7722;
148 }
149
150 /*******************************************/
151
check(alias v1,alias v2,alias dg)152 @property void check(alias v1, alias v2, alias dg)()
153 {
154 void checkImpl(alias v)()
155 {
156 static if (v == 0)
157 static assert(!__traits(compiles, dg(0)));
158 else
159 assert(dg(0) == v);
160 }
161
162 static if (enforceProperty)
163 checkImpl!(v1)();
164 else
165 checkImpl!(v2)();
166 }
167
168 struct S {}
169
foo(int n)170 int foo(int n) { return 1; }
foo(int n,int m)171 int foo(int n, int m) { return 2; }
goo(int[]a)172 int goo(int[] a) { return 1; }
goo(int[]a,int m)173 int goo(int[] a, int m) { return 2; }
bar(S s)174 int bar(S s) { return 1; }
bar(S s,int n)175 int bar(S s, int n) { return 2; }
176
baz(X)177 int baz(X)(X x) { return 1; }
baz(X)178 int baz(X)(X x, int n) { return 2; }
179
180 int temp;
boo(int n)181 ref int boo(int n) { return temp; }
coo(int[]a)182 ref int coo(int[] a) { return temp; }
mar(S s)183 ref int mar(S s) { return temp; }
184
maz(X)185 ref int maz(X)(X x) { return temp; }
186
test7722a()187 void test7722a()
188 {
189 int n;
190 int[] a;
191 S s;
192
193 check!(1, 1, x => foo(4) ); check!(1, 1, x => baz(4) );
194 check!(1, 1, x => 4.foo() ); check!(1, 1, x => 4.baz() );
195 check!(0, 1, x => 4.foo ); check!(0, 1, x => 4.baz );
196 check!(2, 2, x => foo(4, 2) ); check!(2, 2, x => baz(4, 2) );
197 check!(2, 2, x => 4.foo(2) ); check!(2, 2, x => 4.baz(2) );
198 check!(0, 2, x => (4.foo = 2) ); check!(0, 2, x => (4.baz = 2) );
199
200 check!(1, 1, x => goo(a) ); check!(1, 1, x => baz(a) );
201 check!(1, 1, x => a.goo() ); check!(1, 1, x => a.baz() );
202 check!(0, 1, x => a.goo ); check!(0, 1, x => a.baz );
203 check!(2, 2, x => goo(a, 2) ); check!(2, 2, x => baz(a, 2) );
204 check!(2, 2, x => a.goo(2) ); check!(2, 2, x => a.baz(2) );
205 check!(0, 2, x => (a.goo = 2) ); check!(0, 2, x => (a.baz = 2) );
206
207 check!(1, 1, x => bar(s) ); check!(1, 1, x => baz(s) );
208 check!(1, 1, x => s.bar() ); check!(1, 1, x => s.baz() );
209 check!(0, 1, x => s.bar ); check!(0, 1, x => s.baz );
210 check!(2, 2, x => bar(s, 2) ); check!(2, 2, x => baz(s, 2) );
211 check!(2, 2, x => s.bar(2) ); check!(2, 2, x => s.baz(2) );
212 check!(0, 2, x => (s.bar = 2) ); check!(0, 2, x => (s.baz = 2) );
213
214 check!(2, 2, x => ( boo(4) = 2)); check!(2, 2, x => ( maz(4) = 2));
215 check!(0, 2, x => (4.boo = 2)); check!(0, 2, x => (4.maz = 2));
216 check!(2, 2, x => ( coo(a) = 2)); check!(2, 2, x => ( maz(a) = 2));
217 check!(0, 2, x => (a.coo = 2)); check!(0, 2, x => (a.maz = 2));
218 check!(2, 2, x => ( mar(s) = 2)); check!(2, 2, x => ( maz(s) = 2));
219 check!(0, 2, x => (s.mar = 2)); check!(0, 2, x => (s.maz = 2));
220 }
221
hoo(T)222 int hoo(T)(int n) { return 1; }
hoo(T)223 int hoo(T)(int n, int m) { return 2; }
koo(T)224 int koo(T)(int[] a) { return 1; }
koo(T)225 int koo(T)(int[] a, int m) { return 2; }
var(T)226 int var(T)(S s) { return 1; }
var(T)227 int var(T)(S s, int n) { return 2; }
228
vaz(T,X)229 int vaz(T, X)(X x) { return 1; }
vaz(T,X)230 int vaz(T, X)(X x, int n) { return 2; }
231
232 //int temp;
voo(T)233 ref int voo(T)(int n) { return temp; }
woo(T)234 ref int woo(T)(int[] a) { return temp; }
nar(T)235 ref int nar(T)(S s) { return temp; }
236
naz(T,X)237 ref int naz(T, X)(X x) { return temp; }
238
test7722b()239 void test7722b()
240 {
241 int n;
242 int[] a;
243 S s;
244
245 check!(1, 1, x => hoo!int(4) ); check!(1, 1, x => vaz!int(4) );
246 check!(1, 1, x => 4.hoo!int() ); check!(1, 1, x => 4.vaz!int() );
247 check!(0, 1, x => 4.hoo!int ); check!(0, 1, x => 4.vaz!int );
248 check!(2, 2, x => hoo!int(4, 2) ); check!(2, 2, x => vaz!int(4, 2) );
249 check!(2, 2, x => 4.hoo!int(2) ); check!(2, 2, x => 4.vaz!int(2) );
250 check!(0, 2, x => (4.hoo!int = 2) ); check!(0, 2, x => (4.vaz!int = 2) );
251
252 check!(1, 1, x => koo!int(a) ); check!(1, 1, x => vaz!int(a) );
253 check!(1, 1, x => a.koo!int() ); check!(1, 1, x => a.vaz!int() );
254 check!(0, 1, x => a.koo!int ); check!(0, 1, x => a.vaz!int );
255 check!(2, 2, x => koo!int(a, 2) ); check!(2, 2, x => vaz!int(a, 2) );
256 check!(2, 2, x => a.koo!int(2) ); check!(2, 2, x => a.vaz!int(2) );
257 check!(0, 2, x => (a.koo!int = 2) ); check!(0, 2, x => (a.vaz!int = 2) );
258
259 check!(1, 1, x => var!int(s) ); check!(1, 1, x => vaz!int(s) );
260 check!(1, 1, x => s.var!int() ); check!(1, 1, x => s.vaz!int() );
261 check!(0, 1, x => s.var!int ); check!(0, 1, x => s.vaz!int );
262 check!(2, 2, x => var!int(s, 2) ); check!(2, 2, x => vaz!int(s, 2) );
263 check!(2, 2, x => s.var!int(2) ); check!(2, 2, x => s.vaz!int(2) );
264 check!(0, 2, x => (s.var!int = 2) ); check!(0, 2, x => (s.vaz!int = 2) );
265
266 check!(2, 2, x => ( voo!int(4) = 2)); check!(2, 2, x => ( naz!int(4) = 2));
267 check!(0, 2, x => (4.voo!int = 2)); check!(0, 2, x => (4.naz!int = 2));
268 check!(2, 2, x => ( woo!int(a) = 2)); check!(2, 2, x => ( naz!int(a) = 2));
269 check!(0, 2, x => (a.woo!int = 2)); check!(0, 2, x => (a.naz!int = 2));
270 check!(2, 2, x => ( nar!int(s) = 2)); check!(2, 2, x => ( naz!int(s) = 2));
271 check!(0, 2, x => (s.nar!int = 2)); check!(0, 2, x => (s.naz!int = 2));
272 }
273
274 /*******************************************/
275 // 7174
276
test7174()277 void test7174()
278 {
279 @property bool foo7174() { return true; }
280 static if (foo7174) {}
281 }
282
283 /***************************************************/
284 // 7274
285
foo7274()286 @property foo7274(){ return "test"; }
bar7274()287 @property bar7274(){ return "kernel32.lib"; }
288
289 pragma(msg, "decl: ", foo7274); // print "decl: foo", not "decl: test"
290 version(Windows) pragma(lib, bar7274); // Error: pragma lib string expected for library name, not 'bar'
291
test7274()292 void test7274()
293 {
294 pragma(msg, "stmt: ", foo7274); // print "stmt: foo", not "stmt: test"
295 //pragma(lib, bar); // Error: pragma(lib) not allowed as statement
296 }
297
298 /***************************************************/
299 // 7275
300
test7275()301 void test7275()
302 {
303 @property int bar1() { return 0; }
304 @property int bar2() { return 1; }
305 @property int bar3() { return 2; }
306
307 switch (0){
308 case bar1: break;
309 case bar2: ..
310 case bar3: break;
311 default: break;
312 }
313 }
314
315 /*****************************************/
316 // 7538
317
test7538()318 void test7538()
319 {
320 struct P
321 {
322 @property long pr() { return 1; }
323 @property void pr(int) {}
324
325 @property long a1()() { return 1; }
326 @property void a1()(int) {}
327 template a2() { @property long a2() { return 1; } }
328 template a2() { @property void a2(int) {} }
329 template a3() { long a3() @property { return 1; } }
330 template a3() { void a3(int) @property {} }
331
332 static
333 {
334 @property long b1()() { return 1; }
335 @property void b1()(int) {}
336 template b2() { @property long b2() { return 1; } }
337 template b2() { @property void b2(int) {} }
338 template b3() { long b3() @property { return 1; } }
339 template b3() { void b3(int) @property {} }
340 }
341
342 @property long c1(T)() { return 1; }
343 @property long c1(T)(int) { return 1; }
344 template c2(T) { @property long c2() { return 1; } }
345 template c2(T) { @property void c2(int) {} }
346 template c3(T) { long c3() @property { return 1; } }
347 template c3(T) { void c3(int) @property {} }
348
349 static
350 {
351 @property long d1(T)() { return 1; }
352 @property void d1(T)(int) {}
353 template d2(T) { @property long d2() { return 1; } }
354 template d2(T) { @property void d2(int) {} }
355 template d3(T) { long d3() @property { return 1; } }
356 template d3(T) { void d3(int) @property {} }
357 }
358
359 void test()
360 {
361 // TOKvar
362 static assert(is(typeof(pr) == long));
363
364 // TOKtemplate
365 static assert(is(typeof(b1) == long));
366 static assert(is(typeof(b2) == long));
367 static assert(is(typeof(b3) == long));
368
369 // TOKimport
370 static assert(is(typeof(d1!int) == long));
371 static assert(is(typeof(d2!int) == long));
372 static assert(is(typeof(d3!int) == long));
373 }
374 }
375 P p;
376 {
377 // TOKdotvar
378 static assert(is(typeof(p.pr) == long));
379
380 // TOKdottd
381 static assert(is(typeof(p.a1) == long));
382 static assert(is(typeof(p.a2) == long));
383 static assert(is(typeof(p.a3) == long));
384
385 // TOKimport
386 static assert(is(typeof(P.b1) == long));
387 static assert(is(typeof(P.b2) == long));
388 static assert(is(typeof(P.b3) == long));
389
390 // TOKdotti;
391 static assert(is(typeof(p.c1!int) == long));
392 static assert(is(typeof(p.c2!int) == long));
393 static assert(is(typeof(p.c3!int) == long));
394 }
395
396 struct F
397 {
398 long fn() { return 1; }
399 void fn(int) {}
400
401 long a1()() { return 1; }
402 void a1()(int) {}
403 template a2() { long a2() { return 1; } }
404 template a2() { void a2(int) {} }
405
406 static
407 {
408 long b1()() { return 1; }
409 void b1()(int) {}
410 template b2() { long b2() { return 1; } }
411 template b2() { void b2(int) {} }
412 }
413
414 long c1(T)() { return 1; }
415 long c1(T)(int) { return 1; }
416 template c2(T) { long c2() { return 1; } }
417 template c2(T) { void c2(int) {} }
418
419 static
420 {
421 long d1(T)() { return 1; }
422 void d1(T)(int) {}
423 template d2(T) { long d2() { return 1; } }
424 template d2(T) { void d2(int) {} }
425 }
426
427 void test()
428 {
429 // TOKvar
430 static assert( is(typeof(fn) == function));
431
432 // TOKtemplate
433 static assert(!is(typeof(b1) == long));
434 static assert(!is(typeof(b2) == long));
435
436 // TOKimport
437 static assert(!is(typeof(d1!int) == long));
438 static assert(!is(typeof(d2!int) == long));
439 }
440 }
441 F f;
442 {
443 // TOKdotvar
444 static assert(is( typeof(f.fn) == function));
445
446 // TOKdottd
447 static assert(!is(typeof(f.a1) == long));
448 static assert(!is(typeof(f.a2) == long));
449
450 // TOKimport
451 static assert(!is(typeof(F.b1) == long));
452 static assert(!is(typeof(F.b2) == long));
453
454 // TOKdotti;
455 static assert(!is(typeof(f.c1!int) == long));
456 static assert(!is(typeof(f.c2!int) == long));
457 }
458 }
459
460 /*****************************************/
461 // 8251
462
463 struct S8251
464 {
minS8251465 static @property int min() { return 123; }
466 }
T8251_Min()467 @property int T8251_Min() { return 456; }
468
T8251a(int v)469 template T8251a (int v) { int T8251a = v; }
470
471 template T8251b1(int v = S8251.min) { int T8251b1 = v; }
472 template T8251b2(int v = T8251_Min) { int T8251b2 = v; }
473
474 template T8251c1(int v : S8251.min) { int T8251c1 = v; }
475 template T8251c2(int v : T8251_Min) { int T8251c2 = v; }
476
test8251()477 void test8251()
478 {
479 static assert(S8251.min == 123); // OK
480 static assert(T8251_Min == 456); // OK
481 int a0 = T8251a!(S8251.min()); // OK
482 int b0 = T8251a!(T8251_Min()); // OK
483
484 // TemplateValueParameter
485 int a1 = T8251a!(S8251.min); // NG
486 int b1 = T8251a!(T8251_Min); // NG
487
488 // TemplateValueParameterDefault
489 int a2 = T8251b1!(); // NG
490 int b2 = T8251b2!(); // NG
491
492 // TemplateValueParameterSpecialization
493 int a3 = T8251c1!(123); // NG
494 int b3 = T8251c2!(456); // NG
495 }
496
497 /*****************************************/
498 // 9063
499
foo9063()500 @property bool foo9063(){ return true; }
501 static assert(foo9063);
502
503 /*****************************************/
504 // 9234
505
506 class Fizz9234
507 {
bar()508 void bar() {}
509 Foo9234!bar foobar;
510 }
511
Foo9234(alias F)512 struct Foo9234(alias F) {}
Foo9234(string thunk)513 struct Foo9234(string thunk) {}
514
515 /*****************************************/
516 // 10103
517
Getter10103()518 mixin template Getter10103()
519 {
520 @property auto foo() { return v; }
521 @property auto bar()() { return v; }
522 @property auto baz(T)() { return v; }
523
524 static @property auto goo() { return 1; }
525 }
526
Setter10103()527 mixin template Setter10103()
528 {
529 @property void foo(int x) { v = x; }
530 @property void bar()(int x) { v = x; }
531 @property void baz(T)(int x) { v = x; }
532
533 static @property void goo(int x) {}
534 }
535
536 struct Foo10103
537 {
538 int v;
539 mixin Getter10103!();
540 mixin Setter10103!();
541 }
542
test10103()543 void test10103()
544 {
545 auto f = Foo10103(4);
546
547 f.foo;
548 f.foo = 3;
549
550 f.bar;
551 f.bar = 3;
552
553 f.baz!int;
554 f.baz!int = 3;
555
556 Foo10103.goo = 3;
557 }
558
559 /*****************************************/
560 // 10197
561
OriginalType10197(T)562 template OriginalType10197(T)
563 {
564 static if (is(T U == enum))
565 alias OriginalType10197 = U;
566 else
567 static assert(0);
568 }
569
test10197()570 void test10197()
571 {
572 enum E : int { F = -20 }
573 struct S
574 {
575 int val;
576 @trusted @property T as(T)()
577 if (is(T == int) && !is(T == enum))
578 {
579 return cast(T)(val);
580 }
581 @trusted @property T as(T)()
582 if (is(T == enum))
583 {
584 return cast(T)as!(OriginalType10197!T);
585 }
586 }
587
588 S val = S(-20);
589 assert(val.as!int == -20);
590 assert(val.as!E == E.F);
591 }
592
593 /*****************************************/
594
main()595 int main()
596 {
597 test1();
598 test7722();
599 test7722a();
600 test7722b();
601 test7174();
602 test7274();
603 test7275();
604 test7538();
605 test8251();
606 test10103();
607 test10197();
608
609 printf("Success\n");
610 return 0;
611 }
612