http://d.puremagic.com/issues/show_bug.cgi?id=3674
--- Comment #4 from Rainer Schuetze <r.sagita...@gmx.de> 2010-01-20 14:48:34 PST --- The current revision (342) now shows a different error, even with a slightly reduced test case: public class IQGraphicsItem { public QGraphicsObject toGraphicsObject(); public QGraphicsObject toGraphicsObject() const; } public abstract class QGraphicsObject : IQGraphicsItem { public final QGraphicsObject toGraphicsObject() { return null; } // Line 10 public final QGraphicsObject toGraphicsObject() const { return null; } // Line 11 } and causes test.d(11): Error: function test.QGraphicsObject.toGraphicsObject cannot override final function test.QGraphicsObject.toGraphicsObject This is what happens: dmd searches its vtbl for a covariant function that is overridden by "toGraphicsObject() const". The rules in Type::covariant() state, that it's ok to match the non-const version of toGraphicsObject(). This triggers two problems: - The first match is taken, not the best. - The class's vtbl is searched, not the vtbl of the base class. As the non-const version of the function is already matched and placed into the vtbl, the function type might have changed due to covariance. In this case, it is final now. Here's a patch to solve both issues: Index: func.c =================================================================== --- func.c (revision 342) +++ func.c (working copy) @@ -382,7 +382,7 @@ } // Find index of existing function in vtbl[] to override - vi = findVtblIndex(&cd->vtbl, cd->baseClass ? cd->baseClass->vtbl.dim : 0); + vi = cd->baseClass ? findVtblIndex(&cd->baseClass->vtbl, cd->baseClass->vtbl.dim) : -1; switch (vi) { case -1: @@ -426,7 +426,7 @@ return; default: - { FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi]; + { FuncDeclaration *fdv = (FuncDeclaration *)cd->baseClass->vtbl.data[vi]; // This function is covariant with fdv if (fdv->isFinal()) error("cannot override final function %s", fdv->toPrettyChars()); @@ -1689,11 +1689,15 @@ int FuncDeclaration::findVtblIndex(Array *vtbl, int dim) { + FuncDeclaration *mismatch = 0; + int bestvi = -1; for (int vi = 0; vi < dim; vi++) { FuncDeclaration *fdv = ((Dsymbol *)vtbl->data[vi])->isFuncDeclaration(); if (fdv && fdv->ident == ident) { + if (type->equals(fdv->type)) + return vi; int cov = type->covariant(fdv->type); //printf("\tbaseclass cov = %d\n", cov); switch (cov) @@ -1702,14 +1706,15 @@ break; case 1: - return vi; + bestvi = vi; // covariant, but not identical + break; case 2: + if(!mismatch) // give a second chance to find exact match + mismatch = fdv; //type->print(); //fdv->type->print(); //printf("%s %s\n", type->deco, fdv->type->deco); - error("of type %s overrides but is not covariant with %s of type %s", - type->toChars(), fdv->toPrettyChars(), fdv->type->toChars()); break; case 3: @@ -1720,7 +1725,10 @@ } } } - return -1; + if(bestvi < 0 && mismatch) + error("of type %s overrides but is not covariant with %s of type %s", + type->toChars(), mismatch->toPrettyChars(), mismatch->type->toChars()); + return bestvi; } /**************************************************** -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------