Bug 19616 – Result type of ternary operator connecting pointers/slices of class handles broken

Status
NEW
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-01-26T00:52:01Z
Last change time
2024-12-13T19:02:12Z
Keywords
accepts-invalid, rejects-valid, safe
Assigned to
No Owner
Creator
Bolpat
Moved to GitHub: dmd#19533 →

Comments

Comment #0 by qs.il.paperinik — 2019-01-26T00:52:01Z
Connecting two pointers/slices of class handles results in weird error messages and behavior. @safe: // disables constant folding! bool condValue; bool cond() { return condValue; }; class Base { } class Derived : Base { } Base base; Derived derived; static this() { base = new Base; derived = new Derived; condValue = false; } Base[] baseArr; Derived[] derivedArr; In this setup, the expression auto arr = cond() ? baseArr : derivedArr; gives the error message Error: incompatible types for (baseArr) : (derivedArr): Base[] and Derived[] while clearly const(Base)[] is the best common type. If this is not liked, void*[] is another option. Explicitly casting `derivedArr` to `const(Base)[]` solves that. It hinders type inference and usage of `auto`, but fortunately, it won't do actual harm. Creating pointers is no issue. Base* basePtr = &base; Derived* derivedPtr = &derived; Connecting them in a tenery expression gives an undescriptive error message: Error: cannot implicitly convert expression [..] of type Base* to Base* This is useless while the type should be const(Base)*. Surprisingly, this statement compiles: *(cond() ? basePtr : derivedPtr) = new Base(); Note that cond() returns false, i.e. derivedPtr now points to a Base object. Note that this is @safe code.
Comment #1 by qs.il.paperinik — 2019-06-06T21:18:23Z
The same is true for interfaces: interface I { } interface A : I { } bool condValue; bool cond() { return condValue; } pragma(msg, typeof(cond() ? &a : cond() ? &b : &i)); // I* I* iPtr = cond() ? &a : &i; // fails with error message: cannot assign I* to I* const(I)* iPtr = cond() ? &a : &i; // succeeds (cond() ? a : i) = i; // succeeds and breaks @safe
Comment #2 by robert.schadek — 2024-12-13T19:02:12Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19533 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB