is(typeof(...)) vs __traits(compiles, ...)

2020-02-21 Thread drug via Digitalmars-d-learn

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.


Re: is(typeof(...)) vs __traits(compiles, ...)

2020-02-21 Thread Steven Schveighoffer via Digitalmars-d-learn

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