You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 arraypragma(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 elementspragma(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.
The text was updated successfully, but these errors were encountered:
issues.dlang (@jmdavis) commented on 2019-08-04T15:28:20Z
When a template is implicitly instantiated with a dynamic array, the type of the slice of that dynamic array is used (which is tail-const if the dynamic array is const or tail-immutable if it's immutable). It does that so that you don't have to explicitly slice dynamic arrays all over the place when using templated code (though unfortunately, it does mean that dynamic arrays are treated a bit special, since nothing like this happens with other types). Explicitly instantiating a template with a dynamic array uses the exact type, because you're providing the exact type rather than using type inference.
What I don't know is why lambda stuff ends up inferring the exact type of the dynamic array in some cases and the type you get when slicing it in others.
Simen Kjaeraas reported this on 2018-01-19T21:36:43Z
Transferred from https://issues.dlang.org/show_bug.cgi?id=18268
CC List
Description
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.The text was updated successfully, but these errors were encountered: