2 /***************************************************/
3 // https://issues.dlang.org/show_bug.cgi?id=6265
5 pure nothrow @safe int h6265() {
8 int f6265a(alias g
)() {
11 pure nothrow @safe int i6265a() {
12 return f6265a
!h6265();
18 pure nothrow @safe int i6265b() {
22 pure nothrow @safe int i6265c() {
28 /***************************************************/
29 // Make sure a function is not infered as pure if it isn't.
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.
51 static assert( is(typeof(&g
!()) == void delegate() pure nothrow @nogc @safe));
52 static assert(!is(typeof(&g
!()) == void delegate()));
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
)
81 /***************************************************/
82 // https://issues.dlang.org/show_bug.cgi?id=5936
84 auto bug5936c(R
)(R i
) @safe pure nothrow {
87 static assert( bug5936c(0) );
89 /***************************************************/
90 // https://issues.dlang.org/show_bug.cgi?id=6351
92 void bug6351(alias dg
)()
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 {}
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)
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
166 /***************************************************/
167 // https://issues.dlang.org/show_bug.cgi?id=7017
169 template map7017(fun
...) if (fun
.length
>= 1)
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
)()
222 auto escapeShellArgument(alias allocator
)()
224 return escapeArgumentImpl
!allocator();
227 pure string
escapeShellArguments()
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
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
;
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() {}
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
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
; }
350 double foo()(double a
) { return a
* a
; }
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)");
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
373 static assert(!__traits(compiles
, g
++));
378 static assert(!__traits(compiles
, g
++));
382 static assert(is(typeof(&foo1
) == void delegate() pure nothrow @nogc @safe));
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
++));
397 static assert(is(typeof(&bar1
) == void delegate() pure immutable nothrow @nogc @safe));
399 static assert(is(typeof(&bar2
) == void delegate() pure immutable nothrow @nogc @safe));
405 static assert(!__traits(compiles
, g
++));
410 static assert(!__traits(compiles
, g
++));
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
++));
427 static assert(is(typeof(&sm
.foo1
) == void delegate() pure));
429 static assert(is(typeof(&sm
.foo2
) == void delegate() pure));
433 static assert(is(typeof(&si
.bar1
) == void delegate() pure immutable));
435 static assert(is(typeof(&si
.bar2
) == void delegate() pure immutable));
439 // inheritance of pure and @safe
441 void test9148b() pure nothrow @nogc @safe
444 static assert(is(typeof(&nf
) == void delegate() pure nothrow @nogc @safe));
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));
456 static assert(is(typeof(&sf
) == void function() pure nothrow @nogc @safe));
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() {}
471 void bar() // do not inherit PUREfwdref
473 static assert(is(typeof(&bar
) == void delegate()));
476 static assert(is(typeof(&bar
) == void delegate()));
478 static assert(is(typeof(&func9148b
!()) == void function() pure nothrow @nogc @safe));
481 // from fail_compilation/fail283.d
483 pure int double_sqr9148c(int x
)
486 void do_sqr() pure { y
*= y
; }
493 assert(double_sqr9148c(10) == 100);
497 // from fail_compilation/fail348.d
499 void test9148d() pure
501 void g() // implicitly marked as 'pure'
505 // i() and j() are implicitly marked as 'pure'
507 void j() { i(); g(); } // can call i() and g()
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
)
536 // Here lambda should be inferred to weak purity.
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
)
550 static if (impure
) impure10002();
555 Node10002
[] children
;
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
)));
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
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.
587 // [5] During semantic3 process, fc is not @safe on default.
588 static assert(is(typeof(&fc
) == void delegate()));
591 // [1] this is now inferred to @safe by implementing https://issues.dlang.org/show_bug.cgi?id=7511
595 // [2] A!int(0) is now calling @safe function, then fb!T also be inferred to @safe
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
622 void baz(E1
, E2
)(bool cond
)
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
656 void bar()() { a
[1] = 2; }
658 static assert(typeof(bar
!()).stringof
== "pure nothrow @nogc @safe void()"); // nothrow @safe void()
660 pure void test10296()
665 /***************************************************/
666 // https://issues.dlang.org/show_bug.cgi?id=12025
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
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
)
699 return 1 + logOf12542(n
/2);
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
) {}
792 /***************************************************/
793 // https://issues.dlang.org/show_bug.cgi?id=13840
797 int opApply(int delegate(int))
807 void test13840() nothrow
811 foreach (i
; Foo13840()) // generated delegate is throwable
813 func13840(); // throwable function call
820 // Add more tests regarding inferences later.