blob: 32879ce3e4ca08b4d5e22c528a39f3a494fec6f2 [file] [log] [blame]
/*
runnable/traits.d 9091,8972,8971,7027
runnable/test4.d test6()
RUN_OUTPUT:
---
Success
---
*/
extern(C) int printf(const char*, ...);
template TypeTuple(TL...) { alias TypeTuple = TL; }
/********************************************************/
mixin("struct S1 {"~aggrDecl1~"}");
mixin("class C1 {"~aggrDecl1~"}");
enum aggrDecl1 =
q{
alias Type = typeof(this);
int x = 2;
void foo()
{
static assert( is(typeof(Type.x.offsetof)));
static assert( is(typeof(Type.x.mangleof)));
static assert( is(typeof(Type.x.sizeof )));
static assert( is(typeof(Type.x.alignof )));
static assert( is(typeof({ auto n = Type.x.offsetof; })));
static assert( is(typeof({ auto n = Type.x.mangleof; })));
static assert( is(typeof({ auto n = Type.x.sizeof; })));
static assert( is(typeof({ auto n = Type.x.alignof; })));
static assert( is(typeof(Type.x)));
static assert( is(typeof({ auto n = Type.x; })));
static assert( __traits(compiles, Type.x));
static assert( __traits(compiles, { auto n = Type.x; }));
static assert( is(typeof(x.offsetof)));
static assert( is(typeof(x.mangleof)));
static assert( is(typeof(x.sizeof )));
static assert( is(typeof(x.alignof )));
static assert( is(typeof({ auto n = x.offsetof; })));
static assert( is(typeof({ auto n = x.mangleof; })));
static assert( is(typeof({ auto n = x.sizeof; })));
static assert( is(typeof({ auto n = x.alignof; })));
static assert( is(typeof(x)));
static assert( is(typeof({ auto n = x; })));
static assert( __traits(compiles, x));
static assert( __traits(compiles, { auto n = x; }));
with (this)
{
static assert( is(typeof(x.offsetof)));
static assert( is(typeof(x.mangleof)));
static assert( is(typeof(x.sizeof )));
static assert( is(typeof(x.alignof )));
static assert( is(typeof({ auto n = x.offsetof; })));
static assert( is(typeof({ auto n = x.mangleof; })));
static assert( is(typeof({ auto n = x.sizeof; })));
static assert( is(typeof({ auto n = x.alignof; })));
static assert( is(typeof(x)));
static assert( is(typeof({ auto n = x; })));
static assert( __traits(compiles, x));
static assert( __traits(compiles, { auto n = x; }));
}
}
static void bar()
{
static assert( is(typeof(Type.x.offsetof)));
static assert( is(typeof(Type.x.mangleof)));
static assert( is(typeof(Type.x.sizeof )));
static assert( is(typeof(Type.x.alignof )));
static assert( is(typeof({ auto n = Type.x.offsetof; })));
static assert( is(typeof({ auto n = Type.x.mangleof; })));
static assert( is(typeof({ auto n = Type.x.sizeof; })));
static assert( is(typeof({ auto n = Type.x.alignof; })));
static assert( is(typeof(Type.x)));
static assert(!is(typeof({ auto n = Type.x; })));
static assert( __traits(compiles, Type.x));
static assert(!__traits(compiles, { auto n = Type.x; }));
static assert( is(typeof(x.offsetof)));
static assert( is(typeof(x.mangleof)));
static assert( is(typeof(x.sizeof )));
static assert( is(typeof(x.alignof )));
static assert( is(typeof({ auto n = x.offsetof; })));
static assert( is(typeof({ auto n = x.mangleof; })));
static assert( is(typeof({ auto n = x.sizeof; })));
static assert( is(typeof({ auto n = x.alignof; })));
static assert( is(typeof(x)));
static assert(!is(typeof({ auto n = x; })));
static assert( __traits(compiles, x));
static assert(!__traits(compiles, { auto n = x; }));
Type t;
with (t)
{
static assert( is(typeof(x.offsetof)));
static assert( is(typeof(x.mangleof)));
static assert( is(typeof(x.sizeof )));
static assert( is(typeof(x.alignof )));
static assert( is(typeof({ auto n = x.offsetof; })));
static assert( is(typeof({ auto n = x.mangleof; })));
static assert( is(typeof({ auto n = x.sizeof; })));
static assert( is(typeof({ auto n = x.alignof; })));
static assert( is(typeof(x)));
static assert( is(typeof({ auto n = x; })));
static assert( __traits(compiles, x));
static assert( __traits(compiles, { auto n = x; }));
}
}
};
void test1()
{
foreach (Type; TypeTuple!(S1, C1))
{
static assert( is(typeof(Type.x.offsetof)));
static assert( is(typeof(Type.x.mangleof)));
static assert( is(typeof(Type.x.sizeof )));
static assert( is(typeof(Type.x.alignof )));
static assert( is(typeof({ auto n = Type.x.offsetof; })));
static assert( is(typeof({ auto n = Type.x.mangleof; })));
static assert( is(typeof({ auto n = Type.x.sizeof; })));
static assert( is(typeof({ auto n = Type.x.alignof; })));
static assert( is(typeof(Type.x)));
static assert(!is(typeof({ auto n = Type.x; })));
static assert( __traits(compiles, Type.x));
static assert(!__traits(compiles, { auto n = Type.x; }));
Type t;
static assert( is(typeof(t.x.offsetof)));
static assert( is(typeof(t.x.mangleof)));
static assert( is(typeof(t.x.sizeof )));
static assert( is(typeof(t.x.alignof )));
static assert( is(typeof({ auto n = t.x.offsetof; })));
static assert( is(typeof({ auto n = t.x.mangleof; })));
static assert( is(typeof({ auto n = t.x.sizeof; })));
static assert( is(typeof({ auto n = t.x.alignof; })));
static assert( is(typeof(t.x)));
static assert( is(typeof({ auto n = t.x; })));
static assert( __traits(compiles, t.x));
static assert( __traits(compiles, { auto n = t.x; }));
with (t)
{
static assert( is(typeof(x.offsetof)));
static assert( is(typeof(x.mangleof)));
static assert( is(typeof(x.sizeof )));
static assert( is(typeof(x.alignof )));
static assert( is(typeof({ auto n = x.offsetof; })));
static assert( is(typeof({ auto n = x.mangleof; })));
static assert( is(typeof({ auto n = x.sizeof; })));
static assert( is(typeof({ auto n = x.alignof; })));
static assert( is(typeof(x)));
static assert( is(typeof({ auto n = x; })));
static assert( __traits(compiles, x));
static assert( __traits(compiles, { auto n = x; }));
}
}
}
/********************************************************/
void test2()
{
struct S
{
int val;
int[] arr;
int[int] aar;
void foo() {}
void boo()() {}
static void test()
{
static assert(!__traits(compiles, S.foo()));
static assert(!__traits(compiles, S.boo()));
static assert(!__traits(compiles, foo()));
static assert(!__traits(compiles, boo()));
}
}
int v;
int[] a;
void f(int n) {}
static assert( __traits(compiles, S.val)); // 'S.val' is treated just a symbol
static assert(!__traits(compiles, { int n = S.val; }));
static assert(!__traits(compiles, f(S.val)));
static assert(!__traits(compiles, v = S.val) && !__traits(compiles, S.val = v));
static assert(!__traits(compiles, 1 + S.val) && !__traits(compiles, S.val + 1));
static assert(!__traits(compiles, 1 - S.val) && !__traits(compiles, S.val - 1));
static assert(!__traits(compiles, 1 * S.val) && !__traits(compiles, S.val * 1));
static assert(!__traits(compiles, 1 / S.val) && !__traits(compiles, S.val / 1));
static assert(!__traits(compiles, 1 % S.val) && !__traits(compiles, S.val % 1));
static assert(!__traits(compiles, 1 ~ S.arr) && !__traits(compiles, S.arr ~ 1));
static assert(!__traits(compiles, 1 & S.val) && !__traits(compiles, S.val & 1));
static assert(!__traits(compiles, 1 | S.val) && !__traits(compiles, S.val | 1));
static assert(!__traits(compiles, 1 ^ S.val) && !__traits(compiles, S.val ^ 1));
static assert(!__traits(compiles, 1 ~ S.val) && !__traits(compiles, S.val ~ 1));
static assert(!__traits(compiles, 1 ^^ S.val) && !__traits(compiles, S.val ^^ 1));
static assert(!__traits(compiles, 1 << S.val) && !__traits(compiles, S.val << 1));
static assert(!__traits(compiles, 1 >> S.val) && !__traits(compiles, S.val >> 1));
static assert(!__traits(compiles, 1 >>>S.val) && !__traits(compiles, S.val >>>1));
static assert(!__traits(compiles, 1 && S.val) && !__traits(compiles, S.val && 1));
static assert(!__traits(compiles, 1 || S.val) && !__traits(compiles, S.val || 1));
static assert(!__traits(compiles, 1 in S.aar) && !__traits(compiles, S.val || [1:1]));
static assert(!__traits(compiles, 1 <= S.val) && !__traits(compiles, S.val <= 1));
static assert(!__traits(compiles, 1 == S.val) && !__traits(compiles, S.val == 1));
static assert(!__traits(compiles, 1 is S.val) && !__traits(compiles, S.val is 1));
static assert(!__traits(compiles, 1? 1:S.val) && !__traits(compiles, 1? S.val:1));
static assert(!__traits(compiles, (1, S.val)) && !__traits(compiles, (S.val, 1)));
static assert(!__traits(compiles, &S.val));
static assert(!__traits(compiles, S.arr[0]) && !__traits(compiles, [1,2][S.val]));
static assert(!__traits(compiles, S.val++) && !__traits(compiles, S.val--));
static assert(!__traits(compiles, ++S.val) && !__traits(compiles, --S.val));
static assert(!__traits(compiles, v += S.val) && !__traits(compiles, S.val += 1));
static assert(!__traits(compiles, v -= S.val) && !__traits(compiles, S.val -= 1));
static assert(!__traits(compiles, v *= S.val) && !__traits(compiles, S.val *= 1));
static assert(!__traits(compiles, v /= S.val) && !__traits(compiles, S.val /= 1));
static assert(!__traits(compiles, v %= S.val) && !__traits(compiles, S.val %= 1));
static assert(!__traits(compiles, v &= S.val) && !__traits(compiles, S.val &= 1));
static assert(!__traits(compiles, v |= S.val) && !__traits(compiles, S.val |= 1));
static assert(!__traits(compiles, v ^= S.val) && !__traits(compiles, S.val ^= 1));
static assert(!__traits(compiles, a ~= S.val) && !__traits(compiles, S.arr ~= 1));
static assert(!__traits(compiles, v ^^= S.val) && !__traits(compiles, S.val ^^= 1));
static assert(!__traits(compiles, v <<= S.val) && !__traits(compiles, S.val <<= 1));
static assert(!__traits(compiles, v >>= S.val) && !__traits(compiles, S.val >>= 1));
static assert(!__traits(compiles, v >>>=S.val) && !__traits(compiles, S.val >>>=1));
static assert(!__traits(compiles, { auto x = 1 + S.val; }) && !__traits(compiles, { auto x = S.val + 1; }));
static assert(!__traits(compiles, { auto x = 1 - S.val; }) && !__traits(compiles, { auto x = S.val - 1; }));
static assert(!__traits(compiles, { auto x = S.arr ~ 1; }) && !__traits(compiles, { auto x = 1 ~ S.arr; }));
static assert(!__traits(compiles, S.foo()));
static assert(!__traits(compiles, S.boo()));
S.test();
alias foo = S.foo;
alias boo = S.boo;
static assert(!__traits(compiles, foo()));
static assert(!__traits(compiles, boo()));
// static assert(S.val);
struct SW { int a; }
class CW { int a; }
static assert(!__traits(compiles, { with (SW) { int n = a; } }));
static assert(!__traits(compiles, { with (CW) { int n = a; } }));
}
/********************************************************/
struct S3
{
struct T3 { int val; void foo() {} }
T3 member;
alias member this;
static void test()
{
static assert(!__traits(compiles, S3.val = 1 ));
static assert(!__traits(compiles, { S3.val = 1; }));
static assert(!__traits(compiles, T3.val = 1 ));
static assert(!__traits(compiles, { T3.val = 1; }));
static assert(!__traits(compiles, __traits(getMember, S3, "val") = 1 ));
static assert(!__traits(compiles, { __traits(getMember, S3, "val") = 1; }));
static assert(!__traits(compiles, __traits(getMember, T3, "val") = 1 ));
static assert(!__traits(compiles, { __traits(getMember, T3, "val") = 1; }));
static assert(!__traits(compiles, S3.foo() ));
static assert(!__traits(compiles, { S3.foo(); }));
static assert(!__traits(compiles, T3.foo() ));
static assert(!__traits(compiles, { T3.foo(); }));
static assert(!__traits(compiles, __traits(getMember, S3, "foo")() ));
static assert(!__traits(compiles, { __traits(getMember, S3, "foo")(); }));
static assert(!__traits(compiles, __traits(getMember, T3, "foo")() ));
static assert(!__traits(compiles, { __traits(getMember, T3, "foo")(); }));
static assert(!__traits(compiles, __traits(getOverloads, S3, "foo")[0]() ));
static assert(!__traits(compiles, { __traits(getOverloads, S3, "foo")[0](); }));
static assert(!__traits(compiles, __traits(getOverloads, T3, "foo")[0]() ));
static assert(!__traits(compiles, { __traits(getOverloads, T3, "foo")[0](); }));
}
}
void test3()
{
}
/********************************************************/
void test4()
{
static struct R
{
void opIndex(int) {}
void opSlice() {}
void opSlice(int, int) {}
int opDollar() { return 1; }
alias length = opDollar;
}
R val;
static struct S
{
R val;
void foo()
{
static assert(__traits(compiles, val[1])); // TypeSArray
static assert(__traits(compiles, val[])); // TypeDArray
static assert(__traits(compiles, val[0..val.length])); // TypeSlice
}
}
}
/********************************************************/
template Test5(string name, bool result)
{
mixin(`static assert(__traits(compiles, `~name~`.add!"months"(1)) == result);`);
}
static struct Begin5
{
void add(string s)(int n) {}
}
struct IntervalX5(TP)
{
Begin5 begin;
static assert(__traits(compiles, begin.add!"months"(1)) == true);
mixin Test5!("begin", true);
void foo()
{
static assert(__traits(compiles, begin.add!"months"(1)) == true);
mixin Test5!("begin", true);
}
static test()
{
static assert(__traits(compiles, begin.add!"months"(1)) == false);
mixin Test5!("begin", false);
}
}
alias IX5 = IntervalX5!int;
alias beginX5 = IX5.begin;
static assert(__traits(compiles, beginX5.add!"months"(1)) == false);
mixin Test5!("beginG5", false);
void test5()
{
static struct IntervalY5(TP)
{
Begin5 begin;
static assert(__traits(compiles, begin.add!"months"(1)) == true);
mixin Test5!("begin", true);
void foo()
{
static assert(__traits(compiles, begin.add!"months"(1)) == true);
mixin Test5!("begin", true);
}
static test()
{
static assert(__traits(compiles, begin.add!"months"(1)) == false);
mixin Test5!("begin", false);
}
}
alias IX = IntervalX5!int;
alias beginX = IX.begin;
static assert(__traits(compiles, beginX.add!"months"(1)) == false);
mixin Test5!("beginX", false);
alias IY = IntervalY5!int;
alias beginY = IY.begin;
static assert(__traits(compiles, beginY.add!"months"(1)) == false);
mixin Test5!("beginY", false);
}
/********************************************************/
void test6()
{
static struct Foo
{
static struct Bar
{
static int get() { return 0; }
static int val;
void set() { assert(0); }
int num;
}
static class Baz
{
static int get() { return 0; }
static int val;
void set() { assert(0); }
int num;
}
Bar bar;
Baz baz;
}
// allowed cases that do 'use' Foo.bar without this
assert(Foo.bar.get() == 0); // Foo.bar.get()
assert(Foo.baz.get() == 0); // Foo.bar.get()
static assert(!__traits(compiles, Foo.bar.set()));
static assert(!__traits(compiles, Foo.baz.set()));
assert(Foo.bar.val == 0); // Foo.bar.val
assert(Foo.baz.val == 0); // Foo.baz.val
static assert(!__traits(compiles, Foo.bar.num = 1));
static assert(!__traits(compiles, Foo.baz.num = 1));
}
/********************************************************/
struct Tuple7(T...)
{
T field;
enum check1 = is(typeof(field[0] = 1));
enum check2 = is(typeof({ field[0] = 1; }));
this(U, size_t n)(U[n] values)
if (is(typeof({ foreach (i, _; T) field[0] = values[0]; })))
{}
}
void test7()
{
alias Tuple7!(int, int) Tup7;
static assert(Tup7.check1);
static assert(Tup7.check2);
int[2] ints = [ 1, 2 ];
Tup7 t = ints;
struct S7
{
int value;
enum check1 = is(typeof(value = 1));
enum check2 = is(typeof({ value = 1; }));
void foo()(int v)
if (is(typeof({
value = v; // valid
}))) {}
static void bar()(int v)
if (is(typeof({
value = v; // always invalid
}))) {}
}
static assert(S7.check1);
static assert(S7.check2);
S7 s;
s.foo(1);
static assert(!__traits(compiles, S7.bar(1)));
}
/********************************************************/
// 4350
template Mix4350() { int b; }
struct S4350
{
int a;
mixin Mix4350 mix;
int c;
template Func() { void call(int n) { c = n; } }
alias func = Func!();
}
void test4350()
{
S4350 s;
s.a = 1;
s.mix.b = 2;
s.func.call(3);
assert(s.a == 1);
assert(s.b == 2);
assert(s.c == 3);
with (s) { a = 2; }
with (s) { mix.b = 3; }
with (s) { func.call(4); }
assert(s.a == 2);
assert(s.b == 3);
assert(s.c == 4);
}
/********************************************************/
// 6430
auto bug6430(int a)
{
static struct Result2 {}
return 4;
}
auto bug6430(int a, int b)
{
static struct Result2
{
int z;
int y() { return z; }
}
auto t = Result2(1);
return 5;
}
/********************************************************/
// 9619
struct Foo9619 { int x; }
void test9619()
{
void bar()
{
typeof(Foo9619.x) y;
}
}
/********************************************************/
// 9633
class Foo9633
{
void baz() {}
void bar()
{
// CallExp::e1->op == TOKvar
static assert(!compilesWithoutThis9633!baz);
}
void vaz()()
{
static class C
{
// CallExp::e1->op == TOKtemplate
static assert(!__traits(compiles, vaz()));
}
}
}
template compilesWithoutThis9633(alias F)
{
enum bool compilesWithoutThis9633 = __traits(compiles, F());
}
void test9633()
{
auto foo = new Foo9633;
foo.bar();
foo.vaz();
}
/********************************************************/
// 11245
struct Vec11245
{
float[2] f;
}
class Bar11245
{
void func()
{
float[Vec11245.f.length] newVal;
}
}
/********************************************************/
// 11614
struct Tuple11614(T...)
{
T field;
alias field this;
}
struct Foo11614
{
alias Tuple11614!(int) NEW_ARGS;
NEW_ARGS args;
void foo()
{
static if (NEW_ARGS.length == 1)
{}
else
static assert(0);
}
}
/********************************************************/
// 11993
struct S11993
{
void foo()() const
if (is(typeof(this) == const(S11993)))
{}
const void bar()()
if (is(typeof(this) == const(S11993)))
{}
}
void test11993()
{
S11993 s;
s.foo();
s.bar();
}
/********************************************************/
// 15934
class B15934
{
int foo() { return 1; }
int foo() const { return 2; }
}
class C15934 : B15934
{
override int foo() { return 3; }
override int foo() const { return 4; }
void test1()
{
assert(this.foo() == 3);
assert( foo() == 3);
assert(this.B15934.foo() == 1);
assert( B15934.foo() == 1);
}
void test2() const
{
assert(this.foo() == 4);
assert( foo() == 4);
assert(this.B15934.foo() == 2); // OK <- wrongly returns 1
assert( B15934.foo() == 2); // OK <- wrongly returns 1
}
}
void test15934()
{
auto c = new C15934();
c.test1();
c.test2();
}
/********************************************************/
int main()
{
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test4350();
test9619();
test9633();
test15934();
printf("Success\n");
return 0;
}