Thread overview
[Issue 10971] New: assigning derived class to base should not trigger promotion of result
Sep 05, 2013
Maxim Fomin
Sep 05, 2013
Maxim Fomin
Sep 05, 2013
Andrej Mitrovic
Sep 05, 2013
Andrej Mitrovic
September 05, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=10971

           Summary: assigning derived class to base should not trigger
                    promotion of result
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: monarchdodra@gmail.com


--- Comment #0 from monarchdodra@gmail.com 2013-09-05 06:16:03 PDT ---
EG:

//----
class A
{
    A next;
}
class B : A
{}

void main()
{
    B first = new B;
    B last = first;
    //foreach(_ ; 0 .. 10)
        last = (last.next = new B); [1]
}
//----
[1]: Error: cannot implicitly convert expression (last.next = new B) of type
main.A to main.B

When the call the compiler should be able to type the result of "last.next =
new B" as a "B" (the type of "new B"), and not an "A" (the type of
"last.next").

Other usecase:
//----
class A
{
    A next;
}
class B : A
{}

void foo(B){}

void main()
{
    A a;
    foo(a = new B);
}
//----
Error: function main.foo (B _param_0) is not callable using argument types (A)

The workaround is trivial of course, but I'd have expect the compiler could handle it.

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


Maxim Fomin <maxim@maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |maxim@maxim-fomin.ru


--- Comment #1 from Maxim Fomin <maxim@maxim-fomin.ru> 2013-09-05 06:49:10 PDT ---
I doubt it will ever be implemented because it breaks static typing of D. In second example type of a is "A" and not "B" and your request would require compiler to accept/reject sometimes arguments depending on context. For example, initializer for a can be not new B, but Object foo() and in such context compiler cannot know whether returned value is trully B or not.

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



--- Comment #2 from monarchdodra@gmail.com 2013-09-05 07:32:08 PDT ---
(In reply to comment #1)
> I doubt it will ever be implemented because it breaks static typing of D. In second example type of a is "A" and not "B" and your request would require compiler to accept/reject sometimes arguments depending on context. For example, initializer for a can be not new B, but Object foo() and in such context compiler cannot know whether returned value is trully B or not.

Depends on how you see it I guess. I could that I see it that the initializer is "new B", yet *because of context* (assign to "a" while we are at it), it doesn't compile.

But I don't think this has anything to do with context. Just that "a = b" is an operation, and like all operations, it has a return type. I think we could improve what that type is. We could make it "The type A, but implicitly cast-able to B"

That would be "nice to have".

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



--- Comment #3 from Maxim Fomin <maxim@maxim-fomin.ru> 2013-09-05 09:18:04 PDT ---
(In reply to comment #2)
> (In reply to comment #1)
> > I doubt it will ever be implemented because it breaks static typing of D. In second example type of a is "A" and not "B" and your request would require compiler to accept/reject sometimes arguments depending on context. For example, initializer for a can be not new B, but Object foo() and in such context compiler cannot know whether returned value is trully B or not.
> 
> Depends on how you see it I guess. I could that I see it that the initializer is "new B", yet *because of context* (assign to "a" while we are at it), it doesn't compile.
> 
> But I don't think this has anything to do with context. Just that "a = b" is an operation, and like all operations, it has a return type. I think we could improve what that type is. We could make it "The type A, but implicitly cast-able to B"
> 
> That would be "nice to have".

In C in assignment chaining type of expression is defined to be the type of leftmost operand. I don't think you EH is a good reason to break it.

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



--- Comment #4 from monarchdodra@gmail.com 2013-09-05 10:17:41 PDT ---
(In reply to comment #3)
> In C in assignment chaining type of expression is defined to be the type of leftmost operand. I don't think you EH is a good reason to break it.

C doesn't have inheritance.

And I don't want to change that behavior.

I want the compiler to know that making an implicit downcast would be legal in this situation.

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


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich@gmail.com


--- Comment #5 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-09-05 10:51:22 PDT ---
Counterpoint:

-----
class A
{
    A next(A newA) { return new A; }  // does not return B!
}
class B : A
{}

void main()
{
    B first = new B;
    B last = first;
    last = (last.next = new B);
}
-----

If someone changes a field into a property, your code would break.

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



--- Comment #6 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-09-05 10:52:03 PDT ---
(In reply to comment #5)
> If someone changes a field into a property, your code would break.

Although I missed using @property there, but it's the same thing.

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


monarchdodra@gmail.com changed:

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


--- Comment #7 from monarchdodra@gmail.com 2013-09-05 23:09:25 PDT ---
(In reply to comment #5)
> Counterpoint:
> 
> If someone changes a field into a property, your code would break.

I guess that's good enough of an example to conclude that my proposal is not worth following.

TY for taking the time to rebuke.

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