| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6265 |
| |
| pure nothrow @safe int h6265() { |
| return 1; |
| } |
| int f6265a(alias g)() { |
| return g(); |
| } |
| pure nothrow @safe int i6265a() { |
| return f6265a!h6265(); |
| } |
| |
| int f6265b()() { |
| return h6265(); |
| } |
| pure nothrow @safe int i6265b() { |
| return f6265b(); |
| } |
| |
| pure nothrow @safe int i6265c() { |
| return { |
| return h6265(); |
| }(); |
| } |
| |
| /***************************************************/ |
| // Make sure a function is not infered as pure if it isn't. |
| |
| int fNPa() { |
| return 1; |
| } |
| int gNPa()() { |
| return fNPa(); |
| } |
| static assert( __traits(compiles, function int () { return gNPa(); })); |
| static assert(!__traits(compiles, function int () pure { return gNPa(); })); |
| static assert(!__traits(compiles, function int () nothrow { return gNPa(); })); |
| static assert(!__traits(compiles, function int () @safe { return gNPa(); })); |
| |
| /***************************************************/ |
| // Need to ensure the comment in Expression::checkPurity is not violated. |
| |
| void fECPa() { |
| void g()() { |
| void h() { |
| } |
| h(); |
| } |
| static assert( is(typeof(&g!()) == void delegate() pure nothrow @nogc @safe)); |
| static assert(!is(typeof(&g!()) == void delegate())); |
| } |
| |
| void fECPb() { |
| void g()() { |
| void h() { |
| } |
| fECPb(); |
| } |
| static assert(!is(typeof(&g!()) == void delegate() pure)); |
| static assert( is(typeof(&g!()) == void delegate())); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=5635 |
| |
| pure bool foo5635(R = int)(string x) |
| { |
| bool result = false; |
| foreach (dchar d; x) |
| result = true; |
| return result; |
| } |
| |
| void test5635() |
| { |
| foo5635("hi"); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=5936 |
| |
| auto bug5936c(R)(R i) @safe pure nothrow { |
| return true; |
| } |
| static assert( bug5936c(0) ); |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6351 |
| |
| void bug6351(alias dg)() |
| { |
| dg(); |
| } |
| |
| void test6351() |
| { |
| void delegate(int[] a...) deleg6351 = (int[] a...){}; |
| alias bug6351!(deleg6351) baz6531; |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=6359 |
| |
| void impure6359() nothrow @safe @nogc {} |
| void throwable6359() pure @safe @nogc {} |
| void system6359() pure nothrow @nogc {} |
| void gcable6359() pure nothrow @safe {} |
| |
| int global6359; |
| |
| void f6359() pure nothrow @safe @nogc |
| { |
| static assert(!__traits(compiles, impure6359())); |
| static assert(!__traits(compiles, throwable6359())); |
| static assert(!__traits(compiles, system6359())); |
| static assert(!__traits(compiles, gcable6359())); |
| static assert(!__traits(compiles, global6359++)); |
| |
| static assert(!__traits(compiles, { impure6359(); }())); |
| static assert(!__traits(compiles, { throwable6359(); }())); |
| static assert(!__traits(compiles, { system6359(); }())); |
| static assert(!__traits(compiles, { gcable6359(); }())); |
| static assert(!__traits(compiles, { global6359++; }())); |
| } |
| |
| void g6359()() pure nothrow @safe @nogc |
| { |
| static assert(!__traits(compiles, impure6359())); |
| static assert(!__traits(compiles, throwable6359())); |
| static assert(!__traits(compiles, system6359())); |
| static assert(!__traits(compiles, gcable6359())); |
| static assert(!__traits(compiles, global6359++)); |
| |
| static assert(!__traits(compiles, { impure6359(); }())); |
| static assert(!__traits(compiles, { throwable6359(); }())); |
| static assert(!__traits(compiles, { system6359(); }())); |
| static assert(!__traits(compiles, { gcable6359(); }())); |
| static assert(!__traits(compiles, { global6359++; }())); |
| } |
| |
| // attribute inference is not affected by the expressions inside __traits(compiles) |
| void h6359()() |
| { |
| static assert( __traits(compiles, impure6359())); |
| static assert( __traits(compiles, throwable6359())); |
| static assert( __traits(compiles, system6359())); |
| static assert( __traits(compiles, gcable6359())); |
| static assert( __traits(compiles, global6359++)); |
| |
| static assert( __traits(compiles, { impure6359(); }())); |
| static assert( __traits(compiles, { throwable6359(); }())); |
| static assert( __traits(compiles, { system6359(); }())); |
| static assert( __traits(compiles, { gcable6359(); }())); |
| static assert( __traits(compiles, { global6359++; }())); |
| } |
| |
| void test6359() pure nothrow @safe @nogc |
| { |
| f6359(); |
| g6359(); |
| h6359(); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=7017 |
| |
| template map7017(fun...) if (fun.length >= 1) |
| { |
| auto map7017() |
| { |
| struct Result { |
| this(int dummy){} // impure member function -> inferred to pure by fixing issue 10329 |
| } |
| return Result(0); // impure call -> inferred to pure by fixing issue 10329 |
| } |
| } |
| |
| int foo7017(immutable int x) pure nothrow { return 1; } |
| |
| void test7017a() pure |
| { |
| int bar7017(immutable int x) pure nothrow { return 1; } |
| |
| static assert(__traits(compiles, map7017!((){})())); |
| static assert(__traits(compiles, map7017!q{ 1 }())); |
| static assert(__traits(compiles, map7017!foo7017())); |
| static assert(__traits(compiles, map7017!bar7017())); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=7017 (little simpler cases) |
| |
| auto map7017a(alias fun)() { return fun(); } // depends on purity of fun |
| auto map7017b(alias fun)() { return; } // always pure |
| auto map7017c(alias fun)() { return yyy7017(); } // always impure |
| |
| int xxx7017() pure { return 1; } |
| int yyy7017() { return 1; } |
| |
| void test7017b() pure |
| { |
| static assert( __traits(compiles, map7017a!xxx7017() )); |
| static assert(!__traits(compiles, map7017a!yyy7017() )); |
| |
| static assert( __traits(compiles, map7017b!xxx7017() )); |
| static assert( __traits(compiles, map7017b!yyy7017() )); |
| |
| static assert(!__traits(compiles, map7017c!xxx7017() )); |
| static assert(!__traits(compiles, map7017c!yyy7017() )); |
| } |
| |
| /***************************************************/ |
| // Test case from std.process |
| |
| auto escapeArgumentImpl(alias allocator)() |
| { |
| return allocator(); |
| } |
| |
| auto escapeShellArgument(alias allocator)() |
| { |
| return escapeArgumentImpl!allocator(); |
| } |
| |
| pure string escapeShellArguments() |
| { |
| char[] allocator() |
| { |
| return new char[1]; |
| } |
| |
| /* Both escape!allocator and escapeImpl!allocator are impure, |
| * but they are nested template function that instantiated here. |
| * Then calling them from here doesn't break purity. |
| */ |
| return escapeShellArgument!allocator(); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=8234 |
| |
| void test8234() |
| { |
| immutable int x = 0; |
| |
| alias FP = typeof({ enum e = x; return e; }); |
| static assert(is(FP : int function())); |
| |
| auto fp = { enum e = x; return e; }; |
| static assert(is(typeof(fp) : int function())); |
| |
| alias DG = typeof({ auto e = x; return e; }); |
| static assert(is(DG : int delegate())); |
| |
| auto dg = { auto e = x; return e; }; |
| static assert(is(typeof(dg) : int delegate())); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=8504 |
| |
| import core.demangle : demangle; |
| |
| void foo8504()() |
| { |
| static assert(typeof(foo8504!()).stringof == "void()"); |
| static assert(typeof(foo8504!()).mangleof == "FZv"); |
| // static assert(demangle(foo8504!().mangleof) == "void testInference.foo8504!().foo8504()"); |
| } |
| |
| auto toDelegate8504a(F)(auto ref F fp) { return fp; } |
| F toDelegate8504b(F)(auto ref F fp) { return fp; } |
| |
| extern(C) void testC8504() {} |
| |
| void test8504() |
| { |
| static assert(typeof(foo8504!()).stringof == "pure nothrow @nogc @safe void()"); |
| static assert(typeof(foo8504!()).mangleof == "FNaNbNiNfZv"); |
| static assert(demangle(foo8504!().mangleof) == "pure nothrow @nogc @safe void testInference.foo8504!().foo8504()"); |
| |
| auto fp1 = toDelegate8504a(&testC8504); |
| auto fp2 = toDelegate8504b(&testC8504); |
| static assert(is(typeof(fp1) == typeof(fp2))); |
| static assert(typeof(fp1).stringof == "extern (C) void function()"); |
| static assert(typeof(fp2).stringof == "extern (C) void function()"); |
| static assert(typeof(fp1).mangleof == "PUZv"); |
| static assert(typeof(fp2).mangleof == "PUZv"); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=8751 |
| |
| alias bool delegate(in int) pure Bar8751; |
| Bar8751 foo8751a(immutable int x) pure |
| { |
| return y => x > y; // OK |
| } |
| Bar8751 foo8751b(const int x) pure |
| { |
| return y => x > y; // error -> OK |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=8793 |
| |
| alias bool delegate(in int) pure Dg8793; |
| alias bool function(in int) pure Fp8793; |
| |
| Dg8793 foo8793fp1(immutable Fp8793 f) pure { return x => (*f)(x); } // OK |
| Dg8793 foo8793fp2( const Fp8793 f) pure { return x => (*f)(x); } // OK |
| |
| Dg8793 foo8793dg1(immutable Dg8793 f) pure { return x => f(x); } // OK |
| Dg8793 foo8793dg2( const Dg8793 f) pure { return x => f(x); } // OK <- error |
| |
| Dg8793 foo8793pfp1(immutable Fp8793* f) pure { return x => (*f)(x); } // OK |
| Dg8793 foo8793pdg1(immutable Dg8793* f) pure { return x => (*f)(x); } // OK |
| |
| Dg8793 foo8793pfp2(const Fp8793* f) pure { return x => (*f)(x); } // OK <- error |
| Dg8793 foo8793pdg2(const Dg8793* f) pure { return x => (*f)(x); } // OK <- error |
| |
| // general case for the hasPointer type |
| Dg8793 foo8793ptr1(immutable int* p) pure { return x => *p == x; } // OK |
| |
| Dg8793 foo8793ptr2(const int* p) pure { return x => *p == x; } // OK <- error |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9072 |
| |
| struct A9072(T) |
| { |
| this(U)(U x) {} |
| ~this() {} |
| } |
| void test9072() |
| { |
| A9072!int a = A9072!short(); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=5933 |
| // https://issues.dlang.org/show_bug.cgi?id=8504 |
| // Template attribute inferrence doesn't work |
| |
| int foo5933()(int a) { return a*a; } |
| struct S5933 |
| { |
| double foo()(double a) { return a * a; } |
| } |
| // outside function |
| static assert(typeof(foo5933!()).stringof == "pure nothrow @nogc @safe int(int a)"); |
| static assert(typeof(S5933.init.foo!()).stringof == "pure nothrow @nogc @safe double(double a)"); |
| |
| void test5933() |
| { |
| // inside function |
| static assert(typeof(foo5933!()).stringof == "pure nothrow @nogc @safe int(int a)"); |
| static assert(typeof(S5933.init.foo!()).stringof == "pure nothrow @nogc @safe double(double a)"); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9148 |
| |
| void test9148a() pure |
| { |
| static int g; |
| int x; |
| |
| void foo1() /+pure+/ |
| { |
| static assert(!__traits(compiles, g++)); |
| x++; |
| } |
| void foo2() pure |
| { |
| static assert(!__traits(compiles, g++)); |
| x++; |
| } |
| foo1(); |
| static assert(is(typeof(&foo1) == void delegate() pure nothrow @nogc @safe)); |
| foo2(); |
| static assert(is(typeof(&foo2) == void delegate() pure nothrow @nogc @safe)); |
| |
| void bar1() immutable /+pure+/ |
| { |
| static assert(!__traits(compiles, g++)); |
| static assert(!__traits(compiles, x++)); |
| } |
| void bar2() immutable pure |
| { |
| static assert(!__traits(compiles, g++)); |
| static assert(!__traits(compiles, x++)); |
| } |
| bar1(); |
| static assert(is(typeof(&bar1) == void delegate() pure immutable nothrow @nogc @safe)); |
| bar2(); |
| static assert(is(typeof(&bar2) == void delegate() pure immutable nothrow @nogc @safe)); |
| |
| struct S |
| { |
| void foo1() /+pure+/ |
| { |
| static assert(!__traits(compiles, g++)); |
| x++; |
| } |
| void foo2() pure |
| { |
| static assert(!__traits(compiles, g++)); |
| x++; |
| } |
| void bar1() immutable /+pure+/ |
| { |
| static assert(!__traits(compiles, g++)); |
| static assert(!__traits(compiles, x++)); |
| } |
| void bar2() immutable pure |
| { |
| static assert(!__traits(compiles, g++)); |
| static assert(!__traits(compiles, x++)); |
| } |
| } |
| |
| S sm; |
| sm.foo1(); |
| static assert(is(typeof(&sm.foo1) == void delegate() pure)); |
| sm.foo2(); |
| static assert(is(typeof(&sm.foo2) == void delegate() pure)); |
| |
| immutable S si; |
| si.bar1(); |
| static assert(is(typeof(&si.bar1) == void delegate() pure immutable)); |
| si.bar2(); |
| static assert(is(typeof(&si.bar2) == void delegate() pure immutable)); |
| } |
| |
| // ---- |
| // inheritance of pure and @safe |
| |
| void test9148b() pure nothrow @nogc @safe |
| { |
| void nf() {} |
| static assert(is(typeof(&nf) == void delegate() pure nothrow @nogc @safe)); |
| |
| struct NS |
| { |
| void mf() {} |
| static void sf() {} |
| } |
| NS ns; |
| static assert(is(typeof(&ns.mf) == void delegate() pure nothrow @nogc @safe)); |
| static assert(is(typeof(&NS.sf) == void function() pure nothrow @nogc @safe)); |
| |
| static void sf() {} |
| static assert(is(typeof(&sf) == void function() pure nothrow @nogc @safe)); |
| |
| static struct SS |
| { |
| void mf() {} |
| static void sf() {} |
| } |
| SS ss; |
| static assert(is(typeof(&ss.mf) == void delegate() pure nothrow @nogc @safe)); |
| static assert(is(typeof(&SS.sf) == void function() pure nothrow @nogc @safe)); |
| } |
| |
| void impureSystem9148b() {} |
| void func9148b()() |
| { |
| void bar() // do not inherit PUREfwdref |
| { |
| static assert(is(typeof(&bar) == void delegate())); |
| impureSystem9148b(); |
| } |
| static assert(is(typeof(&bar) == void delegate())); |
| } |
| static assert(is(typeof(&func9148b!()) == void function() pure nothrow @nogc @safe)); |
| |
| // ---- |
| // from fail_compilation/fail283.d |
| |
| pure int double_sqr9148c(int x) |
| { |
| int y = x; |
| void do_sqr() pure { y *= y; } |
| do_sqr(); |
| return y; |
| } |
| |
| void test9148c() |
| { |
| assert(double_sqr9148c(10) == 100); |
| } |
| |
| // ---- |
| // from fail_compilation/fail348.d |
| |
| void test9148d() pure |
| { |
| void g() // implicitly marked as 'pure' |
| { |
| void h() pure |
| { |
| // i() and j() are implicitly marked as 'pure' |
| void i() { } |
| void j() { i(); g(); } // can call i() and g() |
| } |
| } |
| } |
| |
| void test9148e() |
| { |
| int x; |
| static assert(is(typeof((int a){ return a + x; }) == int delegate(int) pure nothrow @nogc @safe)); |
| |
| auto dg = (int a){ return a + x; }; |
| static assert(is(typeof(dg) == int delegate(int) pure nothrow @nogc @safe)); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12912 |
| |
| struct S12912(alias fun) |
| { |
| void f() { fun(); } |
| } |
| |
| class C12912 |
| { |
| int n; |
| |
| void f() pure |
| { |
| S12912!(() => n) s; |
| // Here lambda should be inferred to weak purity. |
| |
| s.f(); |
| // And this call will be a pure member function call. |
| } |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10002 |
| |
| void impure10002() {} |
| void remove10002(alias pred, bool impure = false, Range)(Range range) |
| { |
| pred(range[0]); |
| static if (impure) impure10002(); |
| } |
| class Node10002 |
| { |
| Node10002 parent; |
| Node10002[] children; |
| |
| void foo() pure |
| { |
| parent.children.remove10002!(n => n is parent)(); |
| remove10002!(n => n is parent)(parent.children); |
| static assert(!__traits(compiles, parent.children.remove10002x!(n => n is parent, true)())); |
| static assert(!__traits(compiles, remove10002x!(n => n is parent, true)(parent.children))); |
| |
| Node10002 p; |
| p.children.remove10002!(n => n is p)(); |
| remove10002!(n => n is p)(p.children); |
| static assert(!__traits(compiles, p.children.remove10002x!(n => n is p, true)())); |
| static assert(!__traits(compiles, remove10002x!(n => n is p, true)(p.children))); |
| } |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10148 |
| |
| void fa10148() {} // fa is @system |
| |
| auto fb10148(T)() |
| { |
| struct A(S) |
| { |
| // [4] Parent function fb is already inferred to @safe, then |
| // fc is forcely marked @safe on default until 2.052. |
| // But fc should keep attribute inference ability |
| // by overriding the inherited @safe-ty from its parent. |
| void fc(T2)() |
| { |
| // [5] During semantic3 process, fc is not @safe on default. |
| static assert(is(typeof(&fc) == void delegate())); |
| fa10148(); |
| } |
| // [1] this is now inferred to @safe by implementing issue 7511 |
| this(S a) {} |
| } |
| |
| // [2] A!int(0) is now calling @safe function, then fb!T also be inferred to @safe |
| return A!int(0); |
| } |
| |
| void test10148() |
| { |
| fb10148!int.fc!int; // [0] instantiate fb |
| // [3] instantiate fc |
| |
| // [6] After semantic3 done, fc!int is deduced to @system. |
| static assert(is(typeof(&fb10148!int.fc!int) == void delegate() @system)); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10289 |
| |
| void test10289() |
| { |
| void foo(E)() |
| { |
| throw new E(""); |
| } |
| void bar(E1, E2)() |
| { |
| throw new E1(""); |
| throw new E2(""); |
| } |
| void baz(E1, E2)(bool cond) |
| { |
| if (cond) |
| throw new E1(""); |
| else |
| throw new E2(""); |
| } |
| |
| import core.exception; |
| static class MyException : Exception |
| { |
| this(string) @safe pure nothrow { super(""); } |
| } |
| |
| static assert( __traits(compiles, () nothrow { foo!Error(); })); |
| static assert( __traits(compiles, () nothrow { foo!AssertError(); })); |
| |
| static assert(!__traits(compiles, () nothrow { foo!Exception(); })); |
| static assert(!__traits(compiles, () nothrow { foo!MyException(); })); |
| |
| static assert( __traits(compiles, () nothrow { bar!(Error, Exception)(); })); |
| static assert(!__traits(compiles, () nothrow { bar!(Exception, Error)(); })); |
| |
| static assert(!__traits(compiles, () nothrow { baz!(Error, Exception)(); })); |
| static assert(!__traits(compiles, () nothrow { baz!(Exception, Error)(); })); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=10296 |
| |
| void foo10296()() |
| { |
| int[3] a; |
| |
| void bar()() { a[1] = 2; } |
| bar(); |
| static assert(typeof(bar!()).stringof == "pure nothrow @nogc @safe void()"); // nothrow @safe void() |
| } |
| pure void test10296() |
| { |
| foo10296(); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12025 |
| |
| struct Foo12025 |
| { |
| int[5] bar; |
| } |
| |
| void test12025a() pure |
| { |
| enum n1 = typeof(Foo12025.bar).length; // OK |
| enum n2 = Foo12025.bar .length; // OK <- error |
| |
| auto x1 = typeof(Foo12025.bar).length; // OK |
| auto x2 = Foo12025.bar .length; // OK <- error |
| } |
| |
| void test12025b() pure |
| { |
| static int[5] bar; |
| |
| enum n1 = typeof(bar).length; // OK |
| enum n2 = bar .length; // OK <- error |
| |
| auto x1 = typeof(bar).length; // OK |
| auto x2 = bar .length; // OK <- error |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12542 |
| |
| int logOf12542(T)(T n) |
| { |
| if (n) |
| return 1 + logOf12542(n/2); |
| return 0; |
| } |
| |
| void test12542() @safe nothrow pure |
| { |
| int log = logOf12542(9); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12704 |
| |
| void foo12704() @system; |
| alias FP12704 = typeof(function() { foo12704(); }); |
| static assert(is(FP12704 == void function() @system)); |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12970 |
| |
| @system { @safe void f12970a() {} } |
| @system { void f12970b() @safe {} } |
| static assert(is(typeof(&f12970a) == void function() @safe)); |
| static assert(is(typeof(&f12970b) == void function() @safe)); |
| |
| @system { @trusted void f12970c() {} } |
| @system { void f12970d() @trusted {} } |
| static assert(is(typeof(&f12970c) == void function() @trusted)); |
| static assert(is(typeof(&f12970d) == void function() @trusted)); |
| |
| @safe { @system void f12970e() {} } |
| @safe { void f12970f() @system {} } |
| static assert(is(typeof(&f12970e) == void function() @system)); |
| static assert(is(typeof(&f12970f) == void function() @system)); |
| |
| @safe { @trusted void f12970g() {} } |
| @safe { void f12970h() @trusted {} } |
| static assert(is(typeof(&f12970g) == void function() @trusted)); |
| static assert(is(typeof(&f12970h) == void function() @trusted)); |
| |
| @trusted { @safe void f12970i() {} } |
| @trusted { void f12970j() @safe {} } |
| static assert(is(typeof(&f12970i) == void function() @safe)); |
| static assert(is(typeof(&f12970j) == void function() @safe)); |
| |
| @trusted { @system void f12970k() {} } |
| @trusted { void f12970l() @system {} } |
| static assert(is(typeof(&f12970k) == void function() @system)); |
| static assert(is(typeof(&f12970l) == void function() @system)); |
| |
| /***************************************************/ |
| // Parsing prefix STC_FUNCATTR for variable declaration |
| |
| __gshared immutable pure nothrow @property @nogc @safe void function() prefix_qualified_fp1; |
| __gshared{immutable{pure{nothrow{@property{@nogc{@safe{void function() prefix_qualified_fp2;}}}}}}} |
| static assert(typeof(prefix_qualified_fp1).stringof == typeof(prefix_qualified_fp2).stringof); |
| static assert(typeof(prefix_qualified_fp1).stringof |
| == "immutable(void function() pure nothrow @nogc @property @safe)"); |
| |
| const pure nothrow @property @nogc @safe void function()[] prefix_qualified_fp_array1; |
| const{pure{nothrow{@property{@nogc{@safe{void function()[] prefix_qualified_fp_array2;}}}}}} |
| static assert(typeof(prefix_qualified_fp_array1).stringof == typeof(prefix_qualified_fp_array2).stringof); |
| static assert(typeof(prefix_qualified_fp_array1).stringof |
| == "const(void function() pure nothrow @nogc @property @safe[])"); |
| |
| /***************************************************/ |
| // Parsing prefix, intermediate, or postfix @safe for alias declaration |
| |
| @safe alias void function() AliasDecl_FP1; |
| alias @safe void function() AliasDecl_FP2; // is not @safe |
| alias void function() @safe AliasDecl_FP3; |
| static assert(AliasDecl_FP1.stringof == "void function() @safe"); |
| static assert(AliasDecl_FP2.stringof == "void function()"); |
| static assert(AliasDecl_FP3.stringof == "void function() @safe"); |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=13217 |
| |
| void writeln13217(string) {} |
| |
| nothrow void a13217(T)(T x) |
| { |
| try |
| { |
| () { writeln13217("a"); } (); |
| } |
| catch (Exception e) {} |
| } |
| |
| void test13217() |
| { |
| a13217(1); |
| } |
| |
| /***************************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=13840 |
| |
| struct Foo13840 |
| { |
| int opApply(int delegate(int)) |
| { |
| return 0; |
| } |
| } |
| |
| void func13840() |
| { |
| } |
| |
| void test13840() nothrow |
| { |
| try |
| { |
| foreach (i; Foo13840()) // generated delegate is throwable |
| { |
| func13840(); // throwable function call |
| } |
| } |
| catch(Throwable) |
| {} |
| } |
| |
| // Add more tests regarding inferences later. |