// PERMUTE_ARGS: // REQUIRED_ARGS: -o- struct A(Args...) { enum i = 1; // base use case. Args[0].T mBase; static assert(is(typeof(mBase) == B.T)); // chained types Args[0].T.TT mChain; static assert(is(typeof(mChain) == B.T.TT)); // chained packs Args[1+1].FArgs[0] mChainPack; static assert(is(typeof(mChainPack) == B)); // expr enum mExpr = Args[1].i; static assert(mExpr == B.i); // Nested + index eval Args[Args[0].i2].T mNested; static assert(is(typeof(mNested) == B.T)); // index with constexpr Args[i].T mCEIndex; static assert(is(typeof(mCEIndex) == B.T)); // Nested + index with constexpr Args[Args[i].i2].T mNestedCE; static assert(is(typeof(mNestedCE) == B.T)); // alias, base use case alias UBase = Args[0].T; static assert(is(UBase == B.T)); // alias, chained types alias UChain = Args[0].T.TT; static assert(is(UChain == B.T.TT)); // alias, chained packs alias UChainPack = Args[1+1].FArgs[0]; static assert(is(UChainPack == B)); // alias, expr alias uExpr = Args[1].i; static assert(uExpr == B.i); // alias, Nested + index eval alias UNested = Args[Args[0].i2].T; static assert(is(UNested == B.T)); // alias, index with constexpr alias UCEIndex = Args[i].T; static assert(is(UCEIndex == B.T)); // alias, Nested + index with constexpr alias UNextedCE = Args[Args[i].i2].T; static assert(is(UNextedCE == B.T)); } struct B { struct T { struct TT { } } enum i = 6; enum i2 = 0; } struct C(Args...) { alias FArgs = Args; } alias Z = A!(B,B,C!(B,B)); /***************************************************/ // https://issues.dlang.org/show_bug.cgi?id=14889 struct A14889(alias Exc) { alias ExceptionType = Exc; } alias TT14889(Args...) = Args; alias X14889a = TT14889!(A14889!Throwable()); alias Y14889a = X14889a[0].ExceptionType; alias X14889b = TT14889!(A14889!Throwable); alias Y14889b = X14889b[0].ExceptionType; /***************************************************/ // https://issues.dlang.org/show_bug.cgi?id=14889 alias TypeTuple14900(T...) = T; struct S14900 { alias T = int; alias U = TypeTuple14900!(long,string); } alias Types14900 = TypeTuple14900!(S14900, S14900); Types14900[0].T a14900; // Types[0] == S, then typeof(a) == S.T == int Types14900[0].U[1] b14900; // Types[0].U == S.U, then typeof(b) == S.U[1] == string void test14900() { Types14900[0].T a; // Types[0] == S, then typeof(a) == S.T == int Types14900[0].U[1] b; // Types[0].U == S.U, then typeof(b) == S.U[1] == string } /***************************************************/ // https://issues.dlang.org/show_bug.cgi?id=14911 void test14911() { struct S {} int* buf1 = new int[2].ptr; // OK S* buf2 = (new S[2]).ptr; // OK S* buf3 = new S[2].ptr; // OK <- broken } /***************************************************/ // https://issues.dlang.org/show_bug.cgi?id=14986 alias Id14986(alias a) = a; struct Foo14986 { int tsize; } struct Bar14986 { enum Foo14986[] arr = [Foo14986()]; } Bar14986 test14986() { Foo14986[] types; auto a1 = new void[types[0].tsize]; // TypeIdentifier::toExpression auto a2 = new void[Id14986!types[0].tsize]; // TypeInstance::toExpression Bar14986 bar; auto a3 = Id14986!(typeof(bar).arr[0].tsize); // TypeTypeof::resolve auto a4 = Id14986!(typeof(return).arr[0].tsize); // TypeReturn::resolve return Bar14986(); }