www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 18268] New: Inconsistent decay of array types when passed to

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

          Issue ID: 18268
           Summary: Inconsistent decay of array types when passed to
                    different callables
           Product: D
           Version: D2
          Hardware: x86
                OS: Windows
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: simen.kjaras gmail.com

Some of these are not like the others:

unittest {
    auto fn1(U)() { auto u = U.init; return u; }
    alias fn2 = function (t) => t;
    alias fn3 = delegate (t) => t;
    auto fn4(U)(U u) { return u; }

    alias T = const(int[]);
    alias T1 = typeof((function (t) {return t;})(T.init));
    alias T2 = typeof((delegate (t) {return t;})(T.init));
    alias T3 = typeof((t => t)(T.init));
    alias T4 = typeof(() { auto t = T.init; return t; }());
    alias T5 = typeof(fn1!T());
    alias T6 = typeof(fn2(T.init));
    alias T7 = typeof(fn3(T.init));
    alias T8 = typeof(fn4(T.init));

    pragma(msg, T1); // const(int[]) // Const array
    pragma(msg, T2); // const(int[])
    pragma(msg, T3); // const(int[])
    pragma(msg, T4); // const(int[])
    pragma(msg, T5); // const(int[])
    pragma(msg, T6); // const(int)[] // Mutable array of const elements
    pragma(msg, T7); // const(int)[]
    pragma(msg, T8); // const(int)[]
}

The exact same behavior can be observed by changing the type of T to
const(int*).

It seems to me the behavior in T6-T8 is most useful - consider:

unittest {
    import std.range : isInputRange;
    auto fn1(U)(U u) { return isInputRange!U; }
    alias fn2 = t => isInputRange!(typeof(t));
    alias fn3 = function (t) => isInputRange!(typeof(t));
    alias fn4 = delegate (t) => isInputRange!(typeof(t));

    alias T = const(int[]);
    assert(fn1(T.init));
    assert(fn2(T.init));
    assert(fn3(T.init));
    assert(fn4(T.init));
    assert(!((t) => isInputRange!(typeof(t)))(T.init));
    assert(!(function (t){return isInputRange!(typeof(t));})(T.init));
    assert(!(delegate (t){return isInputRange!(typeof(t));})(T.init));
}

It is certainly unexpected that t is an input range only in some cases.

--
Jan 19 2018