blob: bceb4b8586bb28f9b05ae3b760bad453dae3789b [file] [log] [blame]
extern (C) int printf(const(char*) fmt, ...);
static int foo();
/**********************************/
auto red()()
{
return foo();
}
void test13350()
{
int[] data;
assert(is(typeof(red())));
}
/**********************************/
struct A1(T) { void f1() {} }
struct B1(T) { void f2() {} }
A1!(B1!int) func1()() { return typeof(return).init; }
void test1()
{
static if (is(typeof(func1()) R : X!(Y), alias X, Y))
{
R.init.f1();
Y.init.f2();
}
else
static assert(0);
}
/**********************************/
struct A2(T) { void f1() { foo(); } }
struct B2(T) { void f2() { foo(); } }
A2!(B2!int) func2()() { return typeof(return).init; }
void test2()
{
static if (is(typeof(func2())))
{
}
else
static assert(0);
}
/**********************************/
template A3() { void foo() { B3!().bar(); } }
template B3() { void bar() {} }
void test3()
{
// A3!() and B3!() are marked as 'speculative'
static assert(is(typeof(A3!().foo())));
// A3!() is unspeculative, but B3!() isn't.
A3!().foo();
// in codegen phase, B3!() will generate its members, because
// the tinst chain contains unspeculative instance A3!().
}
/**********************************/
struct S4(T)
{
string toString() const { return "instantiated"; }
}
void test4()
{
// inside typeof is not speculative context
alias X = typeof(S4!int());
assert(typeid(X).xtoString !is null);
}
/**********************************/
struct S5(T)
{
string toString() const { return "instantiated"; }
}
void test5()
{
enum x = S5!int();
assert(x.toString() == "instantiated");
}
/**********************************/
int foo6()() { return 0; }
template A6() { alias f = foo6!(); }
void testa6()() if (is(typeof(A6!().f))) {}
template B6() { alias f = foo6!(); }
void testb6()() if (is(typeof(B6!().f))) {}
template C6() { void f() { B6!().f(); } }
void test6()
{
testa6();
// foo6!() is speculatively instantiated from A6!() [TemplateInstance a]
// -> foo6!() is instantiated in A6!(), so it should be inserted to the members of this module.
testb6();
// foo6!() is speculatively instantiated from B6!() [TemplateInstance b],
// but the tinst of cached [TemplateInstance a] is not changed.
// -> insert [b] to the tnext chain of [a]
C6!().f();
// foo6!() is used through C6!(), so it should be linked to the final executable.
// but its first instance does not link to any non-speculative instances.
// -> look for tnext chain and determine its codegen is really necessary.
}
/**********************************/
int main()
{
test13350();
test1();
test2();
test3();
test4();
test5();
test6();
printf("Success\n");
return 0;
}