is(typeof(...)) vs __traits(compiles, ...)
Steven Schveighoffer
schveiguy at gmail.com
Fri Feb 21 14:51:35 UTC 2020
On 2/21/20 5:15 AM, drug wrote:
> Currently this code does not compiles:
> ```
> unittest
> {
> class MyClass
> {
> T opCall(T)(T p)
> {
> return p;
> }
> }
>
> import std.container.array : Array;
>
> Array!MyClass arr;
> }
> ```
> but if you comment out `opCall` in MyClass this code compiles. This is
> caused by this in std.conv(4434):
> ```
> static if (is(typeof(chunk = T(args))))
> chunk = T(args);
> ```
> The reason is that `is(typeof(chunk = T(args)))` returns true but does
> not compiles becase MyClass has `opCall`, compiler calls `opCall` but it
> needs `this` pointer that is unavailable. I replaced it by
> ```
> static if (__traits(compiles, chunk = T(args)))
> chunk = T(args);
> ```
> it works but I'm not sure this good solution. The question is -
> shouldn't `typeof` return false in this case? if so then the right fix
> would be fix typeof.
This is a bug for is(typeof). It should indeed reject that call.
My understanding about __traits(compiles) is that it does some funky
things in terms of allowing compilation that isn't normally allowed,
which is a reason to prefer is(typeof). There are probably bugzilla
issues on this. I remember compiler gurus (maybe Timon?) talking about
this at one point.
I would say file an issue with a minimal test case. Any time you have:
static if(is(typeof(expr))) expr;
It should not error (excepting that there are some cases, such as
expressions which can't technically be statements).
-Steve
More information about the Digitalmars-d-learn
mailing list