On 07/19/2013 11:39 AM, evilrat wrote:

> i think problem is that with a struct we can't just generate code for
> this methods(toHash,opCmp,etc) by comparing its address

That would be wrong. Yes the compiler needs the definition of the struct to generate toHash, opCmp, and toString but note that there is no expression that needs S in that sample code.

The code uses a pointer to S, which happens to have trivial toHash, opCmp, and toString.

I think now I see where the problem is coming from. Note that the three "compiles" lines below do exercise toHash, opCmp, and toString on S*.

import std.stdio;

struct S;

void main()
{
    S* p0, p1;

    int[S*] arr;
    arr[p0] = 0;               // compiles
    writefln("%s", p0);        // compiles
    writeln(p0 < p1);          // compiles

    writeln(p0.toString());    // Error: struct S is forward referenced
}

However, calling toString() directly on the pointer naturally forwards the call to S and that requires the complete definition of the struct.

This seems to be a problem with any template that has to work with pointers. The following template cannot work with a pointer:

import std.stdio;

struct S;

void foo(T)(T val)
{
    writeln("%s", val.toString());    // ERROR
}

void main()
{
    S * p;
    foo(p);
}

So, the solution is to do something like the following:

import std.stdio;

struct S;

void foo(T)(T val)
{
    static if (is (T : U*, U)) {
        writefln("(%s)%s", T.stringof, val);

    } else {
        writefln("%s", val.toString());
    }
}

void main()
{
    S * p;
    foo(p);
}

And I think the following code in std/concurrency.d is the reason:

              ( Variant val )
// ...
                  throw new MessageMismatch(
format("Unexpected message type: expected '%s', got '%s'",
                          exp, val.type.toString()));
              } );

val.type returns a TypeInfo and it seems like there is no TypeInfo special for pointers to incomplete types. Shouldn't there be?

Ali

Reply via email to