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: -------

Reply via email to