d: Merge upstream dmd, druntime 26f049fb26, phobos 330d6a4fd.
[official-gcc.git] / gcc / testsuite / gdc.test / compilable / testInference.d
blobbddbaf4294654dbfe7fa1ee3c3b21fd26afacb7e
2 /***************************************************/
3 // https://issues.dlang.org/show_bug.cgi?id=6265
5 pure nothrow @safe int h6265() {
6 return 1;
8 int f6265a(alias g)() {
9 return g();
11 pure nothrow @safe int i6265a() {
12 return f6265a!h6265();
15 int f6265b()() {
16 return h6265();
18 pure nothrow @safe int i6265b() {
19 return f6265b();
22 pure nothrow @safe int i6265c() {
23 return {
24 return h6265();
25 }();
28 /***************************************************/
29 // Make sure a function is not infered as pure if it isn't.
31 int fNPa() {
32 return 1;
34 int gNPa()() {
35 return fNPa();
37 static assert( __traits(compiles, function int () { return gNPa(); }));
38 static assert(!__traits(compiles, function int () pure { return gNPa(); }));
39 static assert(!__traits(compiles, function int () nothrow { return gNPa(); }));
40 static assert(!__traits(compiles, function int () @safe { return gNPa(); }));
42 /***************************************************/
43 // Need to ensure the comment in Expression::checkPurity is not violated.
45 void fECPa() {
46 void g()() {
47 void h() {
49 h();
51 static assert( is(typeof(&g!()) == void delegate() pure nothrow @nogc @safe));
52 static assert(!is(typeof(&g!()) == void delegate()));
55 void fECPb() {
56 void g()() {
57 void h() {
59 fECPb();
61 static assert(!is(typeof(&g!()) == void delegate() pure));
62 static assert( is(typeof(&g!()) == void delegate()));
65 /***************************************************/
66 // https://issues.dlang.org/show_bug.cgi?id=5635
68 pure bool foo5635(R = int)(string x)
70 bool result = false;
71 foreach (dchar d; x)
72 result = true;
73 return result;
76 void test5635()
78 foo5635("hi");
81 /***************************************************/
82 // https://issues.dlang.org/show_bug.cgi?id=5936
84 auto bug5936c(R)(R i) @safe pure nothrow {
85 return true;
87 static assert( bug5936c(0) );
89 /***************************************************/
90 // https://issues.dlang.org/show_bug.cgi?id=6351
92 void bug6351(alias dg)()
94 dg();
97 void test6351()
99 void delegate(int[] a...) deleg6351 = (int[] a...){};
100 alias bug6351!(deleg6351) baz6531;
103 /***************************************************/
104 // https://issues.dlang.org/show_bug.cgi?id=6359
106 void impure6359() nothrow @safe @nogc {}
107 void throwable6359() pure @safe @nogc {}
108 void system6359() pure nothrow @nogc {}
109 void gcable6359() pure nothrow @safe {}
111 int global6359;
113 void f6359() pure nothrow @safe @nogc
115 static assert(!__traits(compiles, impure6359()));
116 static assert(!__traits(compiles, throwable6359()));
117 static assert(!__traits(compiles, system6359()));
118 static assert(!__traits(compiles, gcable6359()));
119 static assert(!__traits(compiles, global6359++));
121 static assert(!__traits(compiles, { impure6359(); }()));
122 static assert(!__traits(compiles, { throwable6359(); }()));
123 static assert(!__traits(compiles, { system6359(); }()));
124 static assert(!__traits(compiles, { gcable6359(); }()));
125 static assert(!__traits(compiles, { global6359++; }()));
128 void g6359()() pure nothrow @safe @nogc
130 static assert(!__traits(compiles, impure6359()));
131 static assert(!__traits(compiles, throwable6359()));
132 static assert(!__traits(compiles, system6359()));
133 static assert(!__traits(compiles, gcable6359()));
134 static assert(!__traits(compiles, global6359++));
136 static assert(!__traits(compiles, { impure6359(); }()));
137 static assert(!__traits(compiles, { throwable6359(); }()));
138 static assert(!__traits(compiles, { system6359(); }()));
139 static assert(!__traits(compiles, { gcable6359(); }()));
140 static assert(!__traits(compiles, { global6359++; }()));
143 // attribute inference is not affected by the expressions inside __traits(compiles)
144 void h6359()()
146 static assert( __traits(compiles, impure6359()));
147 static assert( __traits(compiles, throwable6359()));
148 static assert( __traits(compiles, system6359()));
149 static assert( __traits(compiles, gcable6359()));
150 static assert( __traits(compiles, global6359++));
152 static assert( __traits(compiles, { impure6359(); }()));
153 static assert( __traits(compiles, { throwable6359(); }()));
154 static assert( __traits(compiles, { system6359(); }()));
155 static assert( __traits(compiles, { gcable6359(); }()));
156 static assert( __traits(compiles, { global6359++; }()));
159 void test6359() pure nothrow @safe @nogc
161 f6359();
162 g6359();
163 h6359();
166 /***************************************************/
167 // https://issues.dlang.org/show_bug.cgi?id=7017
169 template map7017(fun...) if (fun.length >= 1)
171 auto map7017()
173 struct Result {
174 this(int dummy){} // impure member function -> inferred to pure by fixing https://issues.dlang.org/show_bug.cgi?id=10329
176 return Result(0); // impure call -> inferred to pure by fixing https://issues.dlang.org/show_bug.cgi?id=10329
180 int foo7017(immutable int x) pure nothrow { return 1; }
182 void test7017a() pure
184 int bar7017(immutable int x) pure nothrow { return 1; }
186 static assert(__traits(compiles, map7017!((){})()));
187 static assert(__traits(compiles, map7017!q{ 1 }()));
188 static assert(__traits(compiles, map7017!foo7017()));
189 static assert(__traits(compiles, map7017!bar7017()));
192 /***************************************************/
193 // https://issues.dlang.org/show_bug.cgi?id=7017 (little simpler cases)
195 auto map7017a(alias fun)() { return fun(); } // depends on purity of fun
196 auto map7017b(alias fun)() { return; } // always pure
197 auto map7017c(alias fun)() { return yyy7017(); } // always impure
199 int xxx7017() pure { return 1; }
200 int yyy7017() { return 1; }
202 void test7017b() pure
204 static assert( __traits(compiles, map7017a!xxx7017() ));
205 static assert(!__traits(compiles, map7017a!yyy7017() ));
207 static assert( __traits(compiles, map7017b!xxx7017() ));
208 static assert( __traits(compiles, map7017b!yyy7017() ));
210 static assert(!__traits(compiles, map7017c!xxx7017() ));
211 static assert(!__traits(compiles, map7017c!yyy7017() ));
214 /***************************************************/
215 // Test case from std.process
217 auto escapeArgumentImpl(alias allocator)()
219 return allocator();
222 auto escapeShellArgument(alias allocator)()
224 return escapeArgumentImpl!allocator();
227 pure string escapeShellArguments()
229 char[] allocator()
231 return new char[1];
234 /* Both escape!allocator and escapeImpl!allocator are impure,
235 * but they are nested template function that instantiated here.
236 * Then calling them from here doesn't break purity.
238 return escapeShellArgument!allocator();
241 /***************************************************/
242 // https://issues.dlang.org/show_bug.cgi?id=8234
244 void test8234()
246 immutable int x = 0;
248 alias FP = typeof({ enum e = x; return e; });
249 static assert(is(FP : int function()));
251 auto fp = { enum e = x; return e; };
252 static assert(is(typeof(fp) : int function()));
254 alias DG = typeof({ auto e = x; return e; });
255 static assert(is(DG : int delegate()));
257 auto dg = { auto e = x; return e; };
258 static assert(is(typeof(dg) : int delegate()));
261 /***************************************************/
262 // https://issues.dlang.org/show_bug.cgi?id=8504
264 import core.demangle : demangle;
266 void foo8504()()
268 static assert(typeof(foo8504!()).stringof == "void()");
269 static assert(typeof(foo8504!()).mangleof == "FZv");
270 // static assert(demangle(foo8504!().mangleof) == "void testInference.foo8504!().foo8504()");
273 auto toDelegate8504a(F)(auto ref F fp) { return fp; }
274 F toDelegate8504b(F)(auto ref F fp) { return fp; }
276 extern(C) void testC8504() {}
278 void test8504()
280 static assert(typeof(foo8504!()).stringof == "pure nothrow @nogc @safe void()");
281 static assert(typeof(foo8504!()).mangleof == "FNaNbNiNfZv");
282 static assert(demangle(foo8504!().mangleof) == "pure nothrow @nogc @safe void testInference.foo8504!().foo8504()");
284 auto fp1 = toDelegate8504a(&testC8504);
285 auto fp2 = toDelegate8504b(&testC8504);
286 static assert(is(typeof(fp1) == typeof(fp2)));
287 static assert(typeof(fp1).stringof == "extern (C) void function()");
288 static assert(typeof(fp2).stringof == "extern (C) void function()");
289 static assert(typeof(fp1).mangleof == "PUZv");
290 static assert(typeof(fp2).mangleof == "PUZv");
293 /***************************************************/
294 // https://issues.dlang.org/show_bug.cgi?id=8751
296 alias bool delegate(in int) pure Bar8751;
297 Bar8751 foo8751a(immutable int x) pure
299 return y => x > y; // OK
301 Bar8751 foo8751b(const int x) pure
303 return y => x > y; // error -> OK
306 /***************************************************/
307 // https://issues.dlang.org/show_bug.cgi?id=8793
309 alias bool delegate(in int) pure Dg8793;
310 alias bool function(in int) pure Fp8793;
312 Dg8793 foo8793fp1(immutable Fp8793 f) pure { return x => (*f)(x); } // OK
313 Dg8793 foo8793fp2( const Fp8793 f) pure { return x => (*f)(x); } // OK
315 Dg8793 foo8793dg1(immutable Dg8793 f) pure { return x => f(x); } // OK
316 Dg8793 foo8793dg2( const Dg8793 f) pure { return x => f(x); } // OK <- error
318 Dg8793 foo8793pfp1(immutable Fp8793* f) pure { return x => (*f)(x); } // OK
319 Dg8793 foo8793pdg1(immutable Dg8793* f) pure { return x => (*f)(x); } // OK
321 Dg8793 foo8793pfp2(const Fp8793* f) pure { return x => (*f)(x); } // OK <- error
322 Dg8793 foo8793pdg2(const Dg8793* f) pure { return x => (*f)(x); } // OK <- error
324 // general case for the hasPointer type
325 Dg8793 foo8793ptr1(immutable int* p) pure { return x => *p == x; } // OK
327 Dg8793 foo8793ptr2(const int* p) pure { return x => *p == x; } // OK <- error
329 /***************************************************/
330 // https://issues.dlang.org/show_bug.cgi?id=9072
332 struct A9072(T)
334 this(U)(U x) {}
335 ~this() {}
337 void test9072()
339 A9072!int a = A9072!short();
342 /***************************************************/
343 // https://issues.dlang.org/show_bug.cgi?id=5933
344 // https://issues.dlang.org/show_bug.cgi?id=8504
345 // Template attribute inferrence doesn't work
347 int foo5933()(int a) { return a*a; }
348 struct S5933
350 double foo()(double a) { return a * a; }
352 // outside function
353 static assert(typeof(foo5933!()).stringof == "pure nothrow @nogc @safe int(int a)");
354 static assert(typeof(S5933.init.foo!()).stringof == "pure nothrow @nogc @safe double(double a)");
356 void test5933()
358 // inside function
359 static assert(typeof(foo5933!()).stringof == "pure nothrow @nogc @safe int(int a)");
360 static assert(typeof(S5933.init.foo!()).stringof == "pure nothrow @nogc @safe double(double a)");
363 /***************************************************/
364 // https://issues.dlang.org/show_bug.cgi?id=9148
366 void test9148a() pure
368 static int g;
369 int x;
371 void foo1() /+pure+/
373 static assert(!__traits(compiles, g++));
374 x++;
376 void foo2() pure
378 static assert(!__traits(compiles, g++));
379 x++;
381 foo1();
382 static assert(is(typeof(&foo1) == void delegate() pure nothrow @nogc @safe));
383 foo2();
384 static assert(is(typeof(&foo2) == void delegate() pure nothrow @nogc @safe));
386 void bar1() immutable /+pure+/
388 static assert(!__traits(compiles, g++));
389 static assert(!__traits(compiles, x++));
391 void bar2() immutable pure
393 static assert(!__traits(compiles, g++));
394 static assert(!__traits(compiles, x++));
396 bar1();
397 static assert(is(typeof(&bar1) == void delegate() pure immutable nothrow @nogc @safe));
398 bar2();
399 static assert(is(typeof(&bar2) == void delegate() pure immutable nothrow @nogc @safe));
401 struct S
403 void foo1() /+pure+/
405 static assert(!__traits(compiles, g++));
406 x++;
408 void foo2() pure
410 static assert(!__traits(compiles, g++));
411 x++;
413 void bar1() immutable /+pure+/
415 static assert(!__traits(compiles, g++));
416 static assert(!__traits(compiles, x++));
418 void bar2() immutable pure
420 static assert(!__traits(compiles, g++));
421 static assert(!__traits(compiles, x++));
425 S sm;
426 sm.foo1();
427 static assert(is(typeof(&sm.foo1) == void delegate() pure));
428 sm.foo2();
429 static assert(is(typeof(&sm.foo2) == void delegate() pure));
431 immutable S si;
432 si.bar1();
433 static assert(is(typeof(&si.bar1) == void delegate() pure immutable));
434 si.bar2();
435 static assert(is(typeof(&si.bar2) == void delegate() pure immutable));
438 // ----
439 // inheritance of pure and @safe
441 void test9148b() pure nothrow @nogc @safe
443 void nf() {}
444 static assert(is(typeof(&nf) == void delegate() pure nothrow @nogc @safe));
446 struct NS
448 void mf() {}
449 static void sf() {}
451 NS ns;
452 static assert(is(typeof(&ns.mf) == void delegate() pure nothrow @nogc @safe));
453 static assert(is(typeof(&NS.sf) == void function() pure nothrow @nogc @safe));
455 static void sf() {}
456 static assert(is(typeof(&sf) == void function() pure nothrow @nogc @safe));
458 static struct SS
460 void mf() {}
461 static void sf() {}
463 SS ss;
464 static assert(is(typeof(&ss.mf) == void delegate() pure nothrow @nogc @safe));
465 static assert(is(typeof(&SS.sf) == void function() pure nothrow @nogc @safe));
468 void impureSystem9148b() {}
469 void func9148b()()
471 void bar() // do not inherit PUREfwdref
473 static assert(is(typeof(&bar) == void delegate()));
474 impureSystem9148b();
476 static assert(is(typeof(&bar) == void delegate()));
478 static assert(is(typeof(&func9148b!()) == void function() pure nothrow @nogc @safe));
480 // ----
481 // from fail_compilation/fail283.d
483 pure int double_sqr9148c(int x)
485 int y = x;
486 void do_sqr() pure { y *= y; }
487 do_sqr();
488 return y;
491 void test9148c()
493 assert(double_sqr9148c(10) == 100);
496 // ----
497 // from fail_compilation/fail348.d
499 void test9148d() pure
501 void g() // implicitly marked as 'pure'
503 void h() pure
505 // i() and j() are implicitly marked as 'pure'
506 void i() { }
507 void j() { i(); g(); } // can call i() and g()
512 void test9148e()
514 int x;
515 static assert(is(typeof((int a){ return a + x; }) == int delegate(int) pure nothrow @nogc @safe));
517 auto dg = (int a){ return a + x; };
518 static assert(is(typeof(dg) == int delegate(int) pure nothrow @nogc @safe));
521 /***************************************************/
522 // https://issues.dlang.org/show_bug.cgi?id=12912
524 struct S12912(alias fun)
526 void f() { fun(); }
529 class C12912
531 int n;
533 void f() pure
535 S12912!(() => n) s;
536 // Here lambda should be inferred to weak purity.
538 s.f();
539 // And this call will be a pure member function call.
543 /***************************************************/
544 // https://issues.dlang.org/show_bug.cgi?id=10002
546 void impure10002() {}
547 void remove10002(alias pred, bool impure = false, Range)(Range range)
549 pred(range[0]);
550 static if (impure) impure10002();
552 class Node10002
554 Node10002 parent;
555 Node10002[] children;
557 void foo() pure
559 parent.children.remove10002!(n => n is parent)();
560 remove10002!(n => n is parent)(parent.children);
561 static assert(!__traits(compiles, parent.children.remove10002x!(n => n is parent, true)()));
562 static assert(!__traits(compiles, remove10002x!(n => n is parent, true)(parent.children)));
564 Node10002 p;
565 p.children.remove10002!(n => n is p)();
566 remove10002!(n => n is p)(p.children);
567 static assert(!__traits(compiles, p.children.remove10002x!(n => n is p, true)()));
568 static assert(!__traits(compiles, remove10002x!(n => n is p, true)(p.children)));
572 /***************************************************/
573 // https://issues.dlang.org/show_bug.cgi?id=10148
575 void fa10148() {} // fa is @system
577 auto fb10148(T)()
579 struct A(S)
581 // [4] Parent function fb is already inferred to @safe, then
582 // fc is forcely marked @safe on default until 2.052.
583 // But fc should keep attribute inference ability
584 // by overriding the inherited @safe-ty from its parent.
585 void fc(T2)()
587 // [5] During semantic3 process, fc is not @safe on default.
588 static assert(is(typeof(&fc) == void delegate()));
589 fa10148();
591 // [1] this is now inferred to @safe by implementing https://issues.dlang.org/show_bug.cgi?id=7511
592 this(S a) {}
595 // [2] A!int(0) is now calling @safe function, then fb!T also be inferred to @safe
596 return A!int(0);
599 void test10148()
601 fb10148!int.fc!int; // [0] instantiate fb
602 // [3] instantiate fc
604 // [6] After semantic3 done, fc!int is deduced to @system.
605 static assert(is(typeof(&fb10148!int.fc!int) == void delegate() @system));
608 /***************************************************/
609 // https://issues.dlang.org/show_bug.cgi?id=10289
611 void test10289()
613 void foo(E)()
615 throw new E("");
617 void bar(E1, E2)()
619 throw new E1("");
620 throw new E2("");
622 void baz(E1, E2)(bool cond)
624 if (cond)
625 throw new E1("");
626 else
627 throw new E2("");
630 import core.exception;
631 static class MyException : Exception
633 this(string) @safe pure nothrow { super(""); }
636 static assert( __traits(compiles, () nothrow { foo!Error(); }));
637 static assert( __traits(compiles, () nothrow { foo!AssertError(); }));
639 static assert(!__traits(compiles, () nothrow { foo!Exception(); }));
640 static assert(!__traits(compiles, () nothrow { foo!MyException(); }));
642 static assert( __traits(compiles, () nothrow { bar!(Error, Exception)(); }));
643 static assert(!__traits(compiles, () nothrow { bar!(Exception, Error)(); }));
645 static assert(!__traits(compiles, () nothrow { baz!(Error, Exception)(); }));
646 static assert(!__traits(compiles, () nothrow { baz!(Exception, Error)(); }));
649 /***************************************************/
650 // https://issues.dlang.org/show_bug.cgi?id=10296
652 void foo10296()()
654 int[3] a;
656 void bar()() { a[1] = 2; }
657 bar();
658 static assert(typeof(bar!()).stringof == "pure nothrow @nogc @safe void()"); // nothrow @safe void()
660 pure void test10296()
662 foo10296();
665 /***************************************************/
666 // https://issues.dlang.org/show_bug.cgi?id=12025
668 struct Foo12025
670 int[5] bar;
673 void test12025a() pure
675 enum n1 = typeof(Foo12025.bar).length; // OK
676 enum n2 = Foo12025.bar .length; // OK <- error
678 auto x1 = typeof(Foo12025.bar).length; // OK
679 auto x2 = Foo12025.bar .length; // OK <- error
682 void test12025b() pure
684 static int[5] bar;
686 enum n1 = typeof(bar).length; // OK
687 enum n2 = bar .length; // OK <- error
689 auto x1 = typeof(bar).length; // OK
690 auto x2 = bar .length; // OK <- error
693 /***************************************************/
694 // https://issues.dlang.org/show_bug.cgi?id=12542
696 int logOf12542(T)(T n)
698 if (n)
699 return 1 + logOf12542(n/2);
700 return 0;
703 void test12542() @safe nothrow pure
705 int log = logOf12542(9);
708 /***************************************************/
709 // https://issues.dlang.org/show_bug.cgi?id=12704
711 void foo12704() @system;
712 alias FP12704 = typeof(function() { foo12704(); });
713 static assert(is(FP12704 == void function() @system));
715 /***************************************************/
716 // https://issues.dlang.org/show_bug.cgi?id=12970
718 @system { @safe void f12970a() {} }
719 @system { void f12970b() @safe {} }
720 static assert(is(typeof(&f12970a) == void function() @safe));
721 static assert(is(typeof(&f12970b) == void function() @safe));
723 @system { @trusted void f12970c() {} }
724 @system { void f12970d() @trusted {} }
725 static assert(is(typeof(&f12970c) == void function() @trusted));
726 static assert(is(typeof(&f12970d) == void function() @trusted));
728 @safe { @system void f12970e() {} }
729 @safe { void f12970f() @system {} }
730 static assert(is(typeof(&f12970e) == void function() @system));
731 static assert(is(typeof(&f12970f) == void function() @system));
733 @safe { @trusted void f12970g() {} }
734 @safe { void f12970h() @trusted {} }
735 static assert(is(typeof(&f12970g) == void function() @trusted));
736 static assert(is(typeof(&f12970h) == void function() @trusted));
738 @trusted { @safe void f12970i() {} }
739 @trusted { void f12970j() @safe {} }
740 static assert(is(typeof(&f12970i) == void function() @safe));
741 static assert(is(typeof(&f12970j) == void function() @safe));
743 @trusted { @system void f12970k() {} }
744 @trusted { void f12970l() @system {} }
745 static assert(is(typeof(&f12970k) == void function() @system));
746 static assert(is(typeof(&f12970l) == void function() @system));
748 /***************************************************/
749 // Parsing prefix STC_FUNCATTR for variable declaration
751 __gshared immutable pure nothrow @property @nogc @safe void function() prefix_qualified_fp1;
752 __gshared{immutable{pure{nothrow{@property{@nogc{@safe{void function() prefix_qualified_fp2;}}}}}}}
753 static assert(typeof(prefix_qualified_fp1).stringof == typeof(prefix_qualified_fp2).stringof);
754 static assert(typeof(prefix_qualified_fp1).stringof
755 == "immutable(void function() pure nothrow @nogc @property @safe)");
757 const pure nothrow @property @nogc @safe void function()[] prefix_qualified_fp_array1;
758 const{pure{nothrow{@property{@nogc{@safe{void function()[] prefix_qualified_fp_array2;}}}}}}
759 static assert(typeof(prefix_qualified_fp_array1).stringof == typeof(prefix_qualified_fp_array2).stringof);
760 static assert(typeof(prefix_qualified_fp_array1).stringof
761 == "const(void function() pure nothrow @nogc @property @safe[])");
763 /***************************************************/
764 // Parsing prefix, intermediate, or postfix @safe for alias declaration
766 @safe alias void function() AliasDecl_FP1;
767 alias @safe void function() AliasDecl_FP2; // is not @safe
768 alias void function() @safe AliasDecl_FP3;
769 static assert(AliasDecl_FP1.stringof == "void function() @safe");
770 static assert(AliasDecl_FP2.stringof == "void function()");
771 static assert(AliasDecl_FP3.stringof == "void function() @safe");
773 /***************************************************/
774 // https://issues.dlang.org/show_bug.cgi?id=13217
776 void writeln13217(string) {}
778 nothrow void a13217(T)(T x)
782 () { writeln13217("a"); } ();
784 catch (Exception e) {}
787 void test13217()
789 a13217(1);
792 /***************************************************/
793 // https://issues.dlang.org/show_bug.cgi?id=13840
795 struct Foo13840
797 int opApply(int delegate(int))
799 return 0;
803 void func13840()
807 void test13840() nothrow
811 foreach (i; Foo13840()) // generated delegate is throwable
813 func13840(); // throwable function call
816 catch(Throwable)
820 // Add more tests regarding inferences later.