Thread overview
[Issue 3674] New: forward reference error with multiple overloads with same name
Jan 05, 2010
Rainer Schuetze
Jan 05, 2010
Rainer Schuetze
Jan 06, 2010
Eldar Insafutdinov
Jan 18, 2010
Walter Bright
Jan 20, 2010
Rainer Schuetze
Jan 21, 2010
Eldar Insafutdinov
Jan 22, 2010
Walter Bright
Jan 22, 2010
Rainer Schuetze
Jan 31, 2010
Walter Bright
January 05, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3674

           Summary: forward reference error with multiple overloads with
                    same name
           Product: D
           Version: 2.037
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: r.sagitario@gmx.de


--- Comment #0 from Rainer Schuetze <r.sagitario@gmx.de> 2010-01-05 00:24:36 PST ---
The following code fails to compile:

public interface IQGraphicsItem
{
    public QGraphicsObject toGraphicsObject();
    public QGraphicsObject toGraphicsObject() const;
}

public class QGraphicsLineItem : IQGraphicsItem
{
    public final QGraphicsObject toGraphicsObject() { return null; } // Line 10
    public final QGraphicsObject toGraphicsObject() const { return null; }
}

public abstract class QGraphicsObject : IQGraphicsItem // line 14
{
    public final QGraphicsObject toGraphicsObject() { return null; }
    public final QGraphicsObject toGraphicsObject() const { return null; }
}

with error:

test.d(14): Error: class test.QGraphicsObject base class is forward referenced
by QGraphicsObject

Actually the error is caused on by the reference in line 11.
The error does not happen there is only a single method toGraphicsObject().

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 05, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3674


Rainer Schuetze <r.sagitario@gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch


--- Comment #1 from Rainer Schuetze <r.sagitario@gmx.de> 2010-01-05 00:36:08 PST ---
The error occurs when dmd tries to match the overloaded member function to the functions in the base class, but hits the slightly different prototype. It then tries to check the return type for covariance, which fails on the forward referenced class.

here's a patch (or maybe just a workaround as I'm not perfectly sure what this does to erronous declarations), but it also fixes the problem, if the return type is actually a forward referenced covariant class.

Index: func.c ===================================================================
--- func.c    (revision 324)
+++ func.c    (working copy)
@@ -510,9 +510,20 @@
             /* Only need to have a tintro if the vptr
              * offsets differ
              */
+            unsigned errors = global.errors;
+            global.gag++;            // suppress printing of error messages
             int offset;
-            if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
+            int baseOf = fdv->type->nextOf()->isBaseOf(type->nextOf(),
&offset);
+            global.gag--;            // suppress printing of error messages
+            if(errors != global.errors)
             {
+                // any error in isBaseOf() is a forward reference error, so we
bail out
+                global.errors = errors;
+                cd->sizeok = 2;    // can't finish due to forward reference
+                return;
+            }
+            if (baseOf)
+            {
                 ti = fdv->type;
 #if 0
                 if (offset)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 06, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3674


Eldar Insafutdinov <e.insafutdinov@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |e.insafutdinov@gmail.com


--- Comment #2 from Eldar Insafutdinov <e.insafutdinov@gmail.com> 2010-01-06 00:14:03 PST ---
As it implies from the testcase this is a blocker for QtD.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 18, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3674


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com


--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> 2010-01-17 23:55:32 PST ---
Changeset 338

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 20, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3674



--- Comment #4 from Rainer Schuetze <r.sagitario@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: -------
January 21, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3674



--- Comment #5 from Eldar Insafutdinov <e.insafutdinov@gmail.com> 2010-01-21 13:37:38 PST ---
When fixing this also make sure this testcase passes:

public class IQGraphicsItem
{
    public QGraphicsObject toGraphicsObject();
    public const(QGraphicsObject) toGraphicsObject() const;
}

public abstract class QGraphicsObject : IQGraphicsItem
{
    public final QGraphicsObject toGraphicsObject() { return null; }
    public final const(QGraphicsObject) toGraphicsObject() const { return null;
}
}

As it currently doesn't, with a different error message.

Thanks.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 22, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3674



--- Comment #6 from Walter Bright <bugzilla@digitalmars.com> 2010-01-21 20:21:23 PST ---
Changeset 344 for second problem.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 22, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3674



--- Comment #7 from Rainer Schuetze <r.sagitario@gmx.de> 2010-01-22 00:39:03 PST ---
Thanks, it works now. This also fixes issue 3282 which is what happened if you did not use "final" to produce an error at compile time. See comments there for another quirk.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 31, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3674


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #8 from Walter Bright <bugzilla@digitalmars.com> 2010-01-30 22:41:16 PST ---
fixed dmd 1.056 and 2.040

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------