Index: aggregate.h =================================================================== --- aggregate.h (revision 196) +++ aggregate.h (working copy) @@ -220,6 +220,7 @@ #define OFFSET_RUNTIME 0x76543210 virtual int isBaseOf(ClassDeclaration *cd, int *poffset); + virtual int isBaseInfoComplete(); Dsymbol *search(Loc, Identifier *ident, int flags); #if DMDV2 int isFuncHidden(FuncDeclaration *fd); @@ -266,6 +267,7 @@ int isBaseOf(ClassDeclaration *cd, int *poffset); int isBaseOf(BaseClass *bc, int *poffset); const char *kind(); + int isBaseInfoComplete(); int vtblOffset(); #if DMDV2 int isCPPinterface(); Index: class.c =================================================================== --- class.c (revision 196) +++ class.c (working copy) @@ -803,6 +803,23 @@ return 0; } +/********************************************* + * Determine if 'this' has clomplete base class information. + * This is used to detect forward references in covariant overloads. + */ + +int ClassDeclaration::isBaseInfoComplete() +{ + if (!baseClass) + return 0; + for (int i = 0; i < baseclasses.dim; i++) + { BaseClass *b = (BaseClass *)baseclasses.data[i]; + if (!b->base || !b->base->isBaseInfoComplete ()) + return 0; + } + return 1; +} + Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags) { Dsymbol *s; @@ -1322,6 +1339,22 @@ return 0; } +/********************************************* + * Determine if 'this' has clomplete base class information. + * This is used to detect forward references in covariant overloads. + */ + +int InterfaceDeclaration::isBaseInfoComplete() +{ + assert(!baseClass); + for (int i = 0; i < baseclasses.dim; i++) + { BaseClass *b = (BaseClass *)baseclasses.data[i]; + if (!b->base || !b->base->isBaseInfoComplete ()) + return 0; + } + return 1; +} + /**************************************** * Determine if slot 0 of the vtbl[] is reserved for something else. * For class objects, yes, this is where the ClassInfo ptr goes. Index: mtype.c =================================================================== --- mtype.c (revision 196) +++ mtype.c (working copy) @@ -3811,16 +3811,20 @@ t2n->mod == MODconst) goto Lcovariant; - // If t1n is forward referenced: - ClassDeclaration *cd = ((TypeClass *)t1n)->sym; - if (!cd->baseClass && cd->baseclasses.dim && !cd->isInterfaceDeclaration()) - { - return 3; - } + // try it, it might already work for incomplete classes + if (t1n->implicitConvTo(t2n)) + goto Lcovariant; + + // If t1n is forward referenced: + ClassDeclaration *cd = ((TypeClass *)t1n)->sym; + if (!cd->isBaseInfoComplete()) + { + return 3; + } } - if (t1n->implicitConvTo(t2n)) - goto Lcovariant; - } + else if (t1n->implicitConvTo(t2n)) + goto Lcovariant; + } goto Lnotcovariant; Lcovariant: