| /* |
| TEST_OUTPUT: |
| --- |
| runnable/implicit.d(162): Deprecation: slice of static array temporary returned by `pureMaker3c()` assigned to longer lived variable `z1` |
| runnable/implicit.d(163): Deprecation: slice of static array temporary returned by `pureMaker3c()` assigned to longer lived variable `z2` |
| --- |
| |
| RUN_OUTPUT: |
| --- |
| Success |
| --- |
| */ |
| |
| import core.stdc.stdio; |
| |
| /***********************************/ |
| |
| template cat1(T) |
| { |
| T cat1(T i) { return i + 1; } |
| } |
| |
| void test1() |
| { |
| auto a = cat1(1); |
| assert(a == 2); |
| } |
| |
| /***********************************/ |
| |
| template cat2(T) |
| { |
| T cat2(T* p) { return *p + 1; } |
| } |
| |
| void test2() |
| { |
| int i = 1; |
| auto a = cat2(&i); |
| assert(a == 2); |
| assert(typeid(typeof(a)) == typeid(int)); |
| } |
| |
| /***********************************/ |
| |
| struct S3 { } |
| |
| template cat3(T) |
| { |
| T cat3(T* p, S3 s) { return *p + 1; } |
| } |
| |
| void test3() |
| { |
| S3 s; |
| int i = 1; |
| auto a = cat3(&i, s); |
| assert(a == 2); |
| assert(typeid(typeof(a)) == typeid(int)); |
| } |
| |
| /***********************************/ |
| |
| template cat4(T, int N) |
| { |
| T cat4(T[N] p, T[N] q) { return p[0] + N; } |
| } |
| |
| void test4() |
| { |
| int[3] i; |
| i[0] = 7; |
| i[1] = 8; |
| i[2] = 9; |
| auto a = cat4(i, i); |
| assert(a == 10); |
| assert(typeid(typeof(a)) == typeid(int)); |
| } |
| |
| /***********************************/ |
| |
| template cat5(T, U=T*, int V=7) |
| { |
| T cat5(T x) |
| { |
| U u = &x; |
| |
| return x + 3 + *u + V; |
| } |
| } |
| |
| void test5() |
| { |
| int x = 2; |
| |
| auto a = cat5(x); |
| assert(a == 14); |
| assert(typeid(typeof(a)) == typeid(int)); |
| |
| auto b = cat5!(int,int*,8)(x); |
| assert(b == 15); |
| assert(typeid(typeof(b)) == typeid(int)); |
| } |
| |
| /***********************************/ |
| |
| int* pureMaker() pure |
| { |
| return [1,2,3,4].ptr + 1; |
| } |
| |
| void testDIP29_1() |
| { |
| int* p; |
| static assert(!__traits(compiles, { immutable x = p + 3; })); |
| immutable x = pureMaker() + 1; |
| immutable y = pureMaker() - 1; |
| immutable z = 1 + pureMaker(); |
| } |
| |
| /***********************************/ |
| |
| int** pureMaker2() pure |
| { |
| int*[] da = [[11,12,13].ptr, [21,22,23].ptr, [31,32,33].ptr, [41,42,43].ptr]; |
| return da.ptr + 1; |
| } |
| |
| void testDIP29_2() |
| { |
| immutable x2 = pureMaker2() + 1; |
| immutable y2 = pureMaker2() - 1; |
| immutable z2 = 1 + pureMaker2(); |
| } |
| |
| /***********************************/ |
| |
| int[] pureMaker3a() pure |
| { |
| return new int[4]; |
| } |
| |
| int* pureMaker3b() pure |
| { |
| return new int[4].ptr; |
| } |
| |
| int[4] pureMaker3c() pure |
| { |
| int[4] buf; |
| return buf; |
| } |
| |
| void testDIP29_3() |
| { |
| immutable x1 = pureMaker3a()[]; |
| immutable x2 = pureMaker3a()[0..2]; |
| |
| immutable y2 = pureMaker3b()[0..2]; |
| |
| // Conversion from *rvalue* of mutable static array to immutable slice |
| immutable z1 = pureMaker3c()[]; |
| immutable z2 = pureMaker3c()[0..2]; |
| |
| // https://issues.dlang.org/show_bug.cgi?id=12467 |
| // conversion from lvalue of mutable static array to immutable slice |
| char[3] arr = "foo"; |
| static assert(!__traits(compiles, { string str = arr[]; })); |
| } |
| |
| /***********************************/ |
| |
| import core.vararg; |
| |
| int* maker() pure { return null; } |
| int* maker1(int *) pure { return null; } |
| int* function(int *) pure makerfp1; |
| int* maker2(int *, ...) pure { return null; } |
| int* maker3(int) pure { return null; } |
| int* maker4(ref int) pure { return null; } |
| int* maker5(ref immutable int) pure { return null; } |
| |
| void testDIP29_4() |
| { |
| { immutable x = maker1(maker()); } |
| { immutable x = maker1(null); } |
| static assert(__traits(compiles, { immutable x = (*makerfp1)(maker()); })); |
| { shared x = maker1(null); } |
| { immutable x = maker2(null, 3); } |
| { immutable int g; immutable x = maker2(null, 3, &g); } |
| static assert(!__traits(compiles, { int g; immutable x = maker2(null, 3, &g); })); |
| { immutable x = maker3(1); } |
| static assert(!__traits(compiles, { int g; immutable x = maker4(g); })); |
| { immutable int g; immutable x = maker5(g); } |
| } |
| |
| /***********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14155 |
| |
| immutable int g14155; |
| |
| shared static this() { g14155 = 1; } |
| |
| int* make14155m ( int* p) pure { return null; } |
| const(int*) make14155c ( const(int*) p) pure { return &g14155; } |
| immutable(int*) make14155i ( immutable(int*) p) pure { return &g14155; } |
| shared(int*) make14155sm( shared(int*) p) pure { return null; } |
| shared(const int*) make14155sc(shared(const int*) p) pure { return &g14155; } |
| |
| void test14155_for_testDIP29_4() |
| { |
| static assert( __traits(compiles, { int* p = make14155m (null); })); // m <- m (normal) |
| static assert( __traits(compiles, { const(int*) p = make14155m (null); })); // c <- m (normal) |
| static assert( __traits(compiles, { shared(int*) p = make14155m (null); })); // sm <- m (unique) |
| static assert( __traits(compiles, { shared(const int*) p = make14155m (null); })); // sc <- m (unique) |
| static assert( __traits(compiles, { immutable(int*) p = make14155m (null); })); // i <- m (unique) |
| |
| static assert(!__traits(compiles, { int* p = make14155c (null); })); // m <- c (NG) <bugzilla case> |
| static assert( __traits(compiles, { const(int*) p = make14155c (null); })); // c <- c (normal) |
| static assert(!__traits(compiles, { shared(int*) p = make14155c (null); })); // sm <- c (NG) |
| static assert( __traits(compiles, { shared(const int*) p = make14155c (null); })); // sc <- c (unique or immutable global) |
| static assert( __traits(compiles, { immutable(int*) p = make14155c (null); })); // i <- c (unique or immutable global) |
| |
| static assert(!__traits(compiles, { int* p = make14155i (null); })); // m <- i (NG) |
| static assert( __traits(compiles, { const(int*) p = make14155i (null); })); // c <- i (normal) |
| static assert(!__traits(compiles, { shared(int*) p = make14155i (null); })); // sm <- i (NG) |
| static assert( __traits(compiles, { shared(const int*) p = make14155i (null); })); // sc <- i (normal) |
| static assert( __traits(compiles, { immutable(int*) p = make14155i (null); })); // i <- i (normal) |
| |
| static assert( __traits(compiles, { int* p = make14155sm(null); })); // m <- sm (unique) |
| static assert( __traits(compiles, { const(int*) p = make14155sm(null); })); // c <- sm (unique) |
| static assert( __traits(compiles, { shared(int*) p = make14155sm(null); })); // sm <- sm (normal) |
| static assert( __traits(compiles, { shared(const int*) p = make14155sm(null); })); // sc <- sm (normal) |
| static assert( __traits(compiles, { immutable(int*) p = make14155sm(null); })); // i <- sm (unique) |
| |
| static assert(!__traits(compiles, { int* p = make14155sc(null); })); // m <- sc (NG) |
| static assert( __traits(compiles, { const(int*) p = make14155sc(null); })); // c <- sc (unique or immutable global) |
| static assert(!__traits(compiles, { shared(int*) p = make14155sc(null); })); // sm <- sc (NG) |
| static assert( __traits(compiles, { shared(const int*) p = make14155sc(null); })); // sc <- sc (normal) |
| static assert( __traits(compiles, { immutable(int*) p = make14155sc(null); })); // i <- sc |
| |
| int x; |
| int* nestf() pure { return &x; } |
| static assert(!__traits(compiles, { immutable(int*) ip = nestf(); })); |
| } |
| |
| /***********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14141 |
| |
| struct S14141 |
| { |
| Object obj; |
| |
| const(Object) getObj() const pure |
| { |
| return obj; |
| } |
| } |
| |
| void test14141() |
| { |
| const S14141 s; |
| static assert(is(typeof(s.getObj()) == const Object)); // ok |
| static assert(!__traits(compiles, { Object o = s.getObj(); })); // ok <- fails |
| } |
| |
| /***********************************/ |
| |
| int[] test6(int[] a) pure @safe nothrow |
| { |
| return a.dup; |
| } |
| |
| /***********************************/ |
| |
| int*[] pureFoo() pure { return null; } |
| |
| |
| void testDIP29_5() pure |
| { |
| { char[] s; immutable x = s.idup; } |
| { immutable x = (cast(int*[])null).dup; } |
| { immutable x = pureFoo(); } |
| { immutable x = pureFoo().dup; } |
| } |
| |
| /***********************************/ |
| |
| void testDIP29_6() |
| { |
| /******* structs ************/ |
| |
| static assert(__traits(compiles, |
| { |
| static struct S { int *p; } |
| immutable s = new S; // since p is null |
| })); |
| |
| static assert(!__traits(compiles, |
| { |
| __gshared int x; |
| static struct S { int *p = &x; } |
| immutable s = new S; // x is mutable |
| })); |
| |
| static assert(!__traits(compiles, |
| { |
| int y; |
| struct S { int x; void bar() { y = 3; } } |
| immutable s = new S; // nested struct |
| })); |
| |
| static assert(!__traits(compiles, |
| { |
| static struct S { int x; this(int); } |
| immutable s = new S(1); |
| })); |
| |
| static assert(__traits(compiles, |
| { |
| static struct S { int x; this(int) pure; } |
| immutable s = new S(1); |
| })); |
| |
| static assert(__traits(compiles, |
| { |
| static struct S { int* p = void; this(int) pure; } |
| immutable s = new S(1); |
| })); |
| |
| static assert(!__traits(compiles, |
| { |
| static struct S { int* p = void; this(int*) pure; } |
| int x; |
| immutable s = new S(&x); |
| })); |
| |
| static assert(__traits(compiles, |
| { |
| static struct S { int* p = void; this(immutable(int)*) pure; } |
| immutable int x; |
| immutable s = new S(&x); |
| })); |
| |
| static assert(__traits(compiles, |
| { |
| static struct S { int* p = void; this(int*) pure; } |
| immutable s = new S(null); |
| })); |
| |
| /******* classes ************/ |
| |
| static assert(__traits(compiles, |
| { |
| static class S { int *p; } |
| immutable s = new S; // since p is null |
| })); |
| |
| static assert(!__traits(compiles, |
| { |
| __gshared int x; |
| static class S { int *p = &x; } |
| immutable s = new S; // x is mutable |
| })); |
| |
| static assert(!__traits(compiles, |
| { |
| int y; |
| class S { int x; void bar() { y = 3; } } |
| immutable s = new S; // nested class |
| })); |
| |
| static assert(!__traits(compiles, |
| { |
| static class S { int x; this(int); } |
| immutable s = new S(1); |
| })); |
| |
| static assert(__traits(compiles, |
| { |
| static class S { int x; this(int) pure; } |
| immutable s = new S(1); |
| })); |
| |
| static assert(__traits(compiles, |
| { |
| static class S { int* p = void; this(int) pure; } |
| immutable s = new S(1); |
| })); |
| |
| static assert(!__traits(compiles, |
| { |
| static class S { int* p = void; this(int*) pure; } |
| int x; |
| immutable s = new S(&x); |
| })); |
| |
| static assert(__traits(compiles, |
| { |
| static class S { int* p = void; this(immutable(int)*) pure; } |
| immutable int x; |
| immutable s = new S(&x); |
| })); |
| |
| static assert(__traits(compiles, |
| { |
| static class S { int* p = void; this(int*) pure; } |
| immutable s = new S(null); |
| })); |
| } |
| |
| // https://issues.dlang.org/show_bug.cgi?id=14155 |
| |
| void test14155_for_testDIP29_6() |
| { |
| static class CI |
| { |
| int* p; |
| this(int) immutable pure { p = &g14155; } |
| } |
| |
| static assert(!__traits(compiles, { CI c = new immutable CI(1); })); |
| static assert( __traits(compiles, { const CI c = new immutable CI(1); })); |
| static assert( __traits(compiles, { immutable CI c = new immutable CI(1); })); |
| static assert(!__traits(compiles, { shared CI c = new immutable CI(1); })); |
| static assert(!__traits(compiles, { CI c = new const CI(1); })); |
| static assert( __traits(compiles, { const CI c = new const CI(1); })); |
| static assert( __traits(compiles, { immutable CI c = new const CI(1); })); |
| static assert(!__traits(compiles, { shared CI c = new const CI(1); })); |
| } |
| |
| /***********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=13640 |
| |
| struct S13640 |
| { |
| static struct R |
| { |
| int* p; |
| this(inout ref int* p) inout pure { this.p = p; } |
| } |
| |
| int* p; |
| |
| void foo() inout pure |
| { |
| // Implicit conversion from inout(R) to R should be disallowed. |
| static assert(!__traits(compiles, { R r = inout(R)(p); })); |
| } |
| } |
| |
| /***********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=15778 |
| |
| void test15778() |
| { |
| char[] cs = new char[](3); |
| wchar[] ws = new wchar[](3); |
| dchar[] ds = new dchar[](3); |
| |
| cs[] = "abc"; assert(cs == "abc"); |
| cs[] = "def"c; assert(cs == "def"); |
| ws[] = "abc"; assert(ws == "abc"); |
| ws[] = "def"w; assert(ws == "def"); |
| ds[] = "abc"; assert(ds == "abc"); |
| ds[] = "def"d; assert(ds == "def"); |
| |
| static assert(!__traits(compiles, (cs[] = "a"w))); |
| static assert(!__traits(compiles, (cs[] = "a"d))); |
| static assert(!__traits(compiles, (ws[] = "a"c))); |
| static assert(!__traits(compiles, (ws[] = "a"d))); |
| static assert(!__traits(compiles, (ds[] = "a"c))); |
| static assert(!__traits(compiles, (ds[] = "a"w))); |
| } |
| |
| /***********************************/ |
| |
| void main() |
| { |
| test1(); |
| test2(); |
| test3(); |
| test4(); |
| test5(); |
| testDIP29_1(); |
| testDIP29_2(); |
| testDIP29_3(); |
| testDIP29_4(); |
| testDIP29_5(); |
| testDIP29_6(); |
| test15778(); |
| |
| printf("Success\n"); |
| } |