www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - is(typeof(...)) vs __traits(compiles, ...)

reply drug <drug2004 bk.ru> writes:
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.
Feb 21 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
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
Feb 21 2020