www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19616] New: Result type of tenery operator connecting

https://issues.dlang.org/show_bug.cgi?id=19616

          Issue ID: 19616
           Summary: Result type of tenery operator connecting
                    pointers/slices of class handles broken
           Product: D
           Version: D2
          Hardware: x86
                OS: Windows
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: qs.il.paperinik gmail.com

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.

--
Jan 25