The following code:
----
template canPersist(T)
{
enum canPersist = canPersist!(T, typeof(T.tupleof));
}
template canPersist(T, U...)
{
enum canPersist = canPersist!(T, U[0]) && canPersist!(T, U[1..$]);
}
template canPersist(T, U : U*)
{
static assert(0, "is this a bug in dmd? methods shouldn't be in .tupleof");
}
void main()
{
struct Test
{
bool opEquals(ref const Test other) const
{
return true;
}
}
enum foo = canPersist!Test;
}
----
Fails to compile with:
----
prog.d(13): Error: static assert "is this a bug in dmd? methods shouldn't be in .tupleof"
prog.d(3): instantiated from here: canPersist!(Test,void*)
prog.d(25): instantiated from here: canPersist!(Test)
----
Adding additional methods to Test has no effect (they don't show up in .tupleof), same goes for normal fields (providing you add template canPersist(T, U) { enum canPersist = true; }). Iterating over typeof(Test.tupleof) in main() does not give the void* type.
Comment #1 by kennytm — 2011-05-23T15:25:24Z
This is expected. An inner struct contains a context pointer to the scope. Use 'static struct' and that 'void*' member will be gone. To illustrate:
-----------------------------------
void main() {
struct S{ void a(){} }
static struct T{ void b(){} }
pragma(msg, S.tupleof);
pragma(msg, T.tupleof);
}
-----------------------------------
tuple((S).this)
tuple()
-----------------------------------
(Although changing that struct to 'static struct' causes a forward-reference error)
Comment #2 by robert — 2011-05-23T15:58:22Z
Thank you. I'd forgotten that local structs aren't POD.