Bug 2511 – Covariant return type doesn't work with circular import

Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2008-12-13T10:21:00Z
Last change time
2014-04-18T09:12:05Z
Keywords
patch, rejects-valid
Assigned to
nobody
Creator
2korden

Attachments

IDFilenameSummaryContent-TypeSize
456covariance.patchbetter detection if a base class is forward referencedtext/plain2934

Comments

Comment #0 by 2korden — 2008-12-13T10:21:23Z
Here is a sample code that triggers an error: // File I.d module I; import Base; interface I { } interface SubI : I { } // File Base.d module Base; import I; class Base { I create() { return null; } } class Derived : Base { SubI create() { return null; } } Compilation options: "dmd I.d" Note that "dmd Base.d" compiles okay.
Comment #1 by 2korden — 2008-12-13T10:22:36Z
And here is an error message: Base.d(15): function Base.Derived.create of type SubI() overrides but is not covariant with Base.Base.create of type I()
Comment #2 by 2korden — 2008-12-13T10:32:11Z
The error can fixed by removing "import Base;" from the I.d, but unfortunately I can't do this in my application because interfaces have methods that accept and return references to Base and Derived: interface I { void doStuff(Base b); } interface SubI : I { void doStuff(Derived b); } A possible solution is to merge them into a single file (which is not acceptable). You should also have a proper file order to compile them at once: dmd Base I // okay dmd I Base // fails to compile Rising its severity until I find a workaround.
Comment #3 by smjg — 2009-04-13T16:40:52Z
This sounds related to old bug 125. And it occurs in the D1 line too. Also rewriting the summary line as the one that was there was confusing.
Comment #4 by r.sagitario — 2009-09-18T01:07:31Z
Created attachment 456 better detection if a base class is forward referenced The current implementation (as of DMD 2.032) defers covariance analysis only if the base class is not yet semantically analysed and it is not an interface. The patch refines this condition by testing whether the class has any forward referenced base classes or interfaces.
Comment #5 by bugzilla — 2010-08-27T22:33:25Z
The patch breaks this code: class UA { A29 f() { return null; } } class UB : UA { B29 f() { return null; } } class A29 { } class B29 : A29 { }
Comment #6 by bugzilla — 2010-08-27T22:49:56Z
Comment #7 by r.sagitario — 2010-08-28T00:23:08Z
Oh, it's only been tested on interfaces. ClassDeclaration::isBaseInfoComplete() is broken, class Object doesn't need a base class: int ClassDeclaration::isBaseInfoComplete() { if (!baseClass) return ident == Id::Object; ...
Comment #8 by bugzilla — 2010-08-29T12:55:08Z
This now fails: class UA { A29 f() { return null; } } class UB : UA { B29 f() { return null; } } class A29 { } class B29 : A29 { }
Comment #9 by braddr — 2010-08-29T13:08:40Z
NOTE: these tests are part of the dmd svn depot these days.. so if you check it out from dsource you can run them yourself cd $(dir}/dmd/src make cd ../test make It's only known to work on linux, though ought to work on any posix system and will need work to work on windows. Any fixes that are required I'd be happy to fold in.
Comment #10 by bugzilla — 2010-08-29T14:31:42Z