[Issue 7676] New: covariance of out arguments and function subtyping doesn't work
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Fri Mar 9 08:17:43 PST 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7676
Summary: covariance of out arguments and function subtyping
doesn't work
Product: D
Version: D2
Platform: All
OS/Version: All
Status: NEW
Severity: major
Priority: P2
Component: DMD
AssignedTo: nobody at puremagic.com
ReportedBy: kingboscop at gmail.com
--- Comment #0 from Boscop <kingboscop at gmail.com> 2012-03-09 08:17:46 PST ---
The title says it all. Here is a test case (DMD 2.058):
---
// Functions are contravariant in their in-arguments
// and covariant in their out-arguments and return type.
// But DMD seems to ignore this:
import std.stdio;
class A {override string toString(){return "A";}}
class B : A {override string toString(){return "B";}}
void fooA(out A a) {a = new A;}
void fooB(out B b) {b = new B;}
string barA(A a) {return a.toString();}
string barB(B b) {return b.toString();}
void main() {
A a = new A;
a = new B; // correct covariant behavior
assert(a.toString() == "B");
// out arguments should be covariant, so this should work:
fooB(a);
// Error: function test.fooB (out B b) is not callable using argument types
(A)
// Error: cannot implicitly convert expression (a) of type test.A to test.B
void function(out A) foo;
foo = &fooA; // same type, trivial
foo(a); assert(a.toString() == "A");
// this should also work without a cast because
// void function(out B) is a subtype of void function(out A)
// due to the covariance of out arguments
foo = &fooB;
// Error: cannot implicitly convert expression (& fooB) of type void
function(out B b) to void function(out A)
// currently it only works with a cast:
// foo = cast(void function(out A))&fooB;
foo(a);
assert(a.toString() == "B");
B b = new B;
assert(barA(b) == "B"); // correct contravariant behavior
string function(B) bar;
bar = &barB; // same type, trivial
assert(bar(b) == "B");
// string function(A) is a subtype of string function(B)
// due to the contravariance of (in) arguments
// so this should work:
bar = &barA; // Error: cannot implicitly convert expression (& barA) of
type string function(A a) to string function(B)
// currently it only works with a cast:
// bar = cast(string function(B))&barA;
assert(bar(b) == "B");
// this fails as it should, but for the wrong reason:
fooA(b); // Error: cast(A)b is not an lvalue
// it should fail because fooA's 1st argument is covariant and should
therefore only accept supertypes of A (A is also a supertype of A), but B is a
subtype of A
}
---
To me it seems that DMD treats out arguments as contravariant at first (which
then fails due to the implicit cast resulting in an rvalue) and it seems to
ignore covariance and contravariance for function subtyping.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list