The profusion of D's attributes has made delegate signature mismatches all too 
likely thus one must resort to casts too often with e.g. callbacks.

const(short)[] delegate(immutable(int)*) dg1;
immutable(short)[] delegate(const(int)*) pure nothrow @safe dg2;
dg1 = dg2;  // fails (if *any* of storage classes or types don't match)

This problem is nothing new. It has been popping up in discussions and bugzilla 
but was never addressed entirely.

The sketch of the conversion rules:
dg2 is implicitly convertible to dg1 if
 - dg2 could override dg1 if they were class methods, bar polymorphic return 
type covariance; OR
 - each of d2's arguments is implicitly convertible from and binary equivalent 
of dg1's respective argument and dg2's return type is implicitly convertible to 
and binary equivalent of dg1's return type.

The overarching thought is that signature types of both delegates should be 
indistinguishable in compiled binaries to rule out polymorphism** as it 
involves vtable pointer shifting. In the type system, however, the assigned 
delegate may have looser but compatible argument types (note: overloading 
problems don't apply to delegates), a tighter return type, or covariant 
attributes. The "if they were class methods" contortion is my try to ease off 
the implementation -- some compiler code may be reused (I may be wrong).

Please find holes.

-- 
Tomek

** It works with C# delegates, though. Anyone knows how they do it?

Reply via email to