// PERMUTE_ARGS: ref int frvv(); class A {} class B : A {} B restrictedfunc(in const(int)) @safe pure nothrow; A relaxedfunc(in int); void bug3797() { // Cannot convert if the return type or parameters are different void function() vv; void function(int) vi; int function() iv; const(int) function() cv; immutable(int) function() xv; static assert( is(typeof( vv = vv ))); static assert(!is(typeof( vv = vi ))); static assert(!is(typeof( vv = iv ))); static assert(!is(typeof( vv = cv ))); static assert(!is(typeof( vv = xv ))); static assert(!is(typeof( vi = vv ))); static assert( is(typeof( vi = vi ))); static assert(!is(typeof( vi = iv ))); static assert(!is(typeof( vi = cv ))); static assert(!is(typeof( vi = cx ))); static assert(!is(typeof( iv = vv ))); static assert(!is(typeof( iv = vi ))); static assert( is(typeof( iv = iv ))); static assert( is(typeof( iv = cv ))); static assert( is(typeof( iv = xv ))); static assert(!is(typeof( cv = vv ))); static assert( is(typeof( cv = iv ))); static assert(!is(typeof( cv = vi ))); static assert( is(typeof( cv = cv ))); static assert( is(typeof( cv = xv ))); static assert(!is(typeof( xv = vv ))); static assert( is(typeof( xv = iv ))); static assert(!is(typeof( xv = vi ))); static assert( is(typeof( xv = cv ))); static assert( is(typeof( xv = xv ))); int* function() ipfunc; const(int*) function() cipfunc; static assert( is(typeof( cipfunc = ipfunc )) ); static assert(!is(typeof( ipfunc = cipfunc )) ); // functions with different linkages can't convert extern(C) void function() cfunc; extern(D) void function() dfunc; static assert(!is(typeof( cfunc = dfunc ))); static assert(!is(typeof( dfunc = cfunc ))); // ref return can't convert to non-ref return typeof(&frvv) rvv; static assert(!is(typeof( rvv = iv ))); static assert(!is(typeof( rvv = cv ))); static assert(!is(typeof( iv = rvv ))); static assert(!is(typeof( cv = rvv ))); // variadic functions don't mix void function(...) vf; static assert(!is(typeof( vf = vv ))); static assert(!is(typeof( vv = vf ))); // non-nothrow -> nothrow void function() nothrow ntf; static assert(!is(typeof( ntf = vv ))); static assert( is(typeof( vv = ntf ))); // @safe <-> @trusted -> @system void function() @system systemfunc; void function() @trusted trustedfunc; void function() @safe safefunc; static assert( is(typeof( trustedfunc = safefunc ))); static assert( is(typeof( systemfunc = trustedfunc ))); static assert( is(typeof( systemfunc = safefunc ))); static assert( is(typeof( safefunc = trustedfunc ))); static assert(!is(typeof( trustedfunc = systemfunc ))); static assert(!is(typeof( safefunc = systemfunc ))); // pure -> non-pure void function() nonpurefunc; void function() pure purefunc; static assert(!is(typeof( purefunc = nonpurefunc ))); static assert( is(typeof( nonpurefunc = purefunc ))); // Cannot convert parameter storage classes (except const to in and in to const) void function(const(int)) constfunc; void function(in int) infunc; void function(out int) outfunc; void function(ref int) reffunc; void function(lazy int) lazyfunc; static assert(is(typeof( infunc = constfunc ))); static assert(is(typeof( constfunc = infunc ))); static assert(!is(typeof( infunc = outfunc ))); static assert(!is(typeof( infunc = reffunc ))); static assert(!is(typeof( infunc = lazyfunc ))); static assert(!is(typeof( outfunc = infunc ))); static assert(!is(typeof( outfunc = reffunc ))); static assert(!is(typeof( outfunc = lazyfunc ))); static assert(!is(typeof( reffunc = infunc ))); static assert(!is(typeof( reffunc = outfunc ))); static assert(!is(typeof( reffunc = lazyfunc ))); static assert(!is(typeof( lazyfunc = infunc ))); static assert(!is(typeof( lazyfunc = outfunc ))); static assert(!is(typeof( lazyfunc = reffunc ))); // Test class covariance A function() afunc; B function() bfunc; static assert( is(typeof( afunc = bfunc ))); static assert(!is(typeof( bfunc = afunc ))); // Test all the conversions at once typeof(&restrictedfunc) prestrictedfunc; typeof(&relaxedfunc) prelaxedfunc = prestrictedfunc; } void bug3797dg() { ref int frvv() { return *(new int); } B restrictedfunc(in const(int)) @safe pure nothrow { return null; } A relaxedfunc(in int) { return null; } // Cannot convert if the return type or parameters are different void delegate() vv; void delegate(int) vi; int delegate() iv; const(int) delegate() cv; immutable(int) delegate() xv; static assert( is(typeof( vv = vv ))); static assert(!is(typeof( vv = vi ))); static assert(!is(typeof( vv = iv ))); static assert(!is(typeof( vv = cv ))); static assert(!is(typeof( vv = xv ))); static assert(!is(typeof( vi = vv ))); static assert( is(typeof( vi = vi ))); static assert(!is(typeof( vi = iv ))); static assert(!is(typeof( vi = cv ))); static assert(!is(typeof( vi = cx ))); static assert(!is(typeof( iv = vv ))); static assert(!is(typeof( iv = vi ))); static assert( is(typeof( iv = iv ))); static assert( is(typeof( iv = cv ))); static assert( is(typeof( iv = xv ))); static assert(!is(typeof( cv = vv ))); static assert( is(typeof( cv = iv ))); static assert(!is(typeof( cv = vi ))); static assert( is(typeof( cv = cv ))); static assert( is(typeof( cv = xv ))); static assert(!is(typeof( xv = vv ))); static assert( is(typeof( xv = iv ))); static assert(!is(typeof( xv = vi ))); static assert( is(typeof( xv = cv ))); static assert( is(typeof( xv = xv ))); int* delegate() ipfunc; const(int*) delegate() cipfunc; static assert( is(typeof( cipfunc = ipfunc )) ); static assert(!is(typeof( ipfunc = cipfunc )) ); // delegates with different linkages can't convert extern(C) void delegate() cfunc; extern(D) void delegate() dfunc; static assert(!is(typeof( cfunc = dfunc ))); static assert(!is(typeof( dfunc = cfunc ))); // ref return can't convert to non-ref return typeof(&frvv) rvv; static assert(!is(typeof( rvv = iv ))); static assert(!is(typeof( rvv = cv ))); static assert(!is(typeof( iv = rvv ))); static assert(!is(typeof( cv = rvv ))); // variadic delegates don't mix void delegate(...) vf; static assert(!is(typeof( vf = vv ))); static assert(!is(typeof( vv = vf ))); // non-nothrow -> nothrow void delegate() nothrow ntf; static assert(!is(typeof( ntf = vv ))); static assert( is(typeof( vv = ntf ))); // @safe <-> @trusted -> @system void delegate() @system systemfunc; void delegate() @trusted trustedfunc; void delegate() @safe safefunc; static assert( is(typeof( trustedfunc = safefunc ))); static assert( is(typeof( systemfunc = trustedfunc ))); static assert( is(typeof( systemfunc = safefunc ))); static assert( is(typeof( safefunc = trustedfunc ))); static assert(!is(typeof( trustedfunc = systemfunc ))); static assert(!is(typeof( safefunc = systemfunc ))); // pure -> non-pure void delegate() nonpurefunc; void delegate() pure purefunc; static assert(!is(typeof( purefunc = nonpurefunc ))); static assert( is(typeof( nonpurefunc = purefunc ))); // Cannot convert parameter storage classes (except const to in and in to const) void delegate(const(int)) constfunc; void delegate(in int) infunc; void delegate(out int) outfunc; void delegate(ref int) reffunc; void delegate(lazy int) lazyfunc; static assert(is(typeof( infunc = constfunc ))); static assert(is(typeof( constfunc = infunc ))); static assert(!is(typeof( infunc = outfunc ))); static assert(!is(typeof( infunc = reffunc ))); static assert(!is(typeof( infunc = lazyfunc ))); static assert(!is(typeof( outfunc = infunc ))); static assert(!is(typeof( outfunc = reffunc ))); static assert(!is(typeof( outfunc = lazyfunc ))); static assert(!is(typeof( reffunc = infunc ))); static assert(!is(typeof( reffunc = outfunc ))); static assert(!is(typeof( reffunc = lazyfunc ))); static assert(!is(typeof( lazyfunc = infunc ))); static assert(!is(typeof( lazyfunc = outfunc ))); static assert(!is(typeof( lazyfunc = reffunc ))); // Test class covariance A delegate() afunc; B delegate() bfunc; static assert( is(typeof( afunc = bfunc ))); static assert(!is(typeof( bfunc = afunc ))); // Test all the conversions at once typeof(&restrictedfunc) prestrictedfunc; typeof(&relaxedfunc) prelaxedfunc = prestrictedfunc; } void bug3268() { auto a = &bug3268; const b = a; assert(a == a); assert(a == b); assert(b == b); immutable c = cast(immutable)a; assert(a == c); assert(b == c); assert(c == c); static assert(is(typeof(*a) == typeof(*b))); static assert(is(typeof(*a) == typeof(*c))); } void bug3268dg() { void bug3268x() {} auto a = &bug3268x; const b = a; assert(a == a); assert(a == b); assert(b == b); immutable c = cast(immutable)a; assert(a == c); assert(b == c); assert(c == c); } void bug3833() { bool b; void function() func; void function() pure purefunc; void function() nothrow nothrowfunc; void function() @safe safefunc; void function() @trusted trustedfunc; static assert( is(typeof( b ? func : purefunc ) == typeof( func ))); static assert( is(typeof( b ? func : nothrowfunc ) == typeof( func ))); static assert( is(typeof( b ? func : safefunc ) == typeof( func ))); static assert( is(typeof( b ? func : trustedfunc ) == typeof( func ))); static assert( is(typeof( b ? purefunc : nothrowfunc ) == typeof( func ))); static assert( is(typeof( b ? purefunc : safefunc ) == typeof( func ))); static assert( is(typeof( b ? purefunc : trustedfunc ) == typeof( func ))); static assert( is(typeof( b ? nothrowfunc : safefunc ) == typeof( func ))); static assert( is(typeof( b ? nothrowfunc : trustedfunc ) == typeof( func ))); static assert( is(typeof( b ? safefunc : trustedfunc ) == typeof( trustedfunc ))); auto arr = [func, purefunc, nothrowfunc, safefunc, trustedfunc]; static assert( is(typeof( arr ) == typeof(func)[]) ); } void bug3833dg() { bool b; void delegate() func; void delegate() pure purefunc; void delegate() nothrow nothrowfunc; void delegate() @safe safefunc; void delegate() @trusted trustedfunc; static assert( is(typeof( b ? func : purefunc ) == typeof( func ))); static assert( is(typeof( b ? func : nothrowfunc ) == typeof( func ))); static assert( is(typeof( b ? func : safefunc ) == typeof( func ))); static assert( is(typeof( b ? func : trustedfunc ) == typeof( func ))); static assert( is(typeof( b ? purefunc : nothrowfunc ) == typeof( func ))); static assert( is(typeof( b ? purefunc : safefunc ) == typeof( func ))); static assert( is(typeof( b ? purefunc : trustedfunc ) == typeof( func ))); static assert( is(typeof( b ? nothrowfunc : safefunc ) == typeof( func ))); static assert( is(typeof( b ? nothrowfunc : trustedfunc ) == typeof( func ))); static assert( is(typeof( b ? safefunc : trustedfunc ) == typeof( trustedfunc ))); auto arr = [func, purefunc, nothrowfunc, safefunc, trustedfunc]; static assert( is(typeof( arr ) == typeof(func)[]) ); } void bug4838() { void delegate() const dgc; static assert(typeof(dgc).stringof == "void delegate() const"); void delegate() immutable dgi; static assert(typeof(dgi).stringof == "void delegate() immutable"); void delegate() shared dgs; static assert(typeof(dgs).stringof == "void delegate() shared"); void delegate() shared const dgsc; static assert(typeof(dgsc).stringof == "void delegate() shared const"); void delegate() inout dgw; static assert(typeof(dgw).stringof == "void delegate() inout"); void delegate() shared inout dgsw; static assert(typeof(dgsw).stringof == "void delegate() shared inout"); } void test8822() { struct S { void foo() const {} } S s; void delegate() const dg = &s.foo; // OK void foo(void delegate() const dg){} // OK struct Foo(T) {} alias Foo!(void delegate() const) X; // NG -> OK } void main() { static assert(is(typeof(&main) P : U*, U)); auto x = cast(void*)&main; const void * p = &main; __gshared void function() gp = null; __gshared void delegate() gp2 = null; }