bug in compiles?

Alex AJ at gmail.com
Fri Apr 12 13:16:23 UTC 2019


On Friday, 12 April 2019 at 09:43:01 UTC, Jacob Carlborg wrote:
> On 2019-04-11 20:13, Alex wrote:
>> The following code works when I comment out the static if
>> 
>> //static if (__traits(compiles, __traits(getAttributes, T)))
>>     static foreach(a;  __traits(getAttributes, T)) Attributes 
>> ~=
>> 
>> 
>> There seems to be absolutely no reason why this code would 
>> fail with the static if but pass without it but in the first 
>> case I get no attributes because the __traits compiles fails.
>> 
>> 
>> 
>> __traits(compiles, __traits(getAttributes, T))
>> 
>> vs
>> 
>> __traits(getAttributes, T)
>> 
>> How could it not compile in the first case and yet work in the 
>> foreach?
>
> The problem is that "__traits(getAttributes, T)" in it self is 
> not valid code. It needs to be part of larger expression or 
> statement. The following seems to work:
>
> https://run.dlang.io/is/JWkdbQ


So this suggests that the error is due to an expression, I 
thought compiles could take expressions ;/

onlineapp.d(17): Error: tuple(3) has no effect
3-int

@(3) int a;
__traits(getAttributes, a);

I use the same semantics all over the place and it seems to work:

static if (__traits(compiles, __traits(isTemplate, T)))


The same issue will happen, but I believe static if works here 
without issue. If so this means that it is a bug. Maybe compiles 
can have handle certain primitives(such as bools here) but not 
others(such as tuples in the main case)?

It would make little sense to be forced to use a temp variable:

static if (__traits(compiles, auto x = __traits(isTemplate, T)))

(after all, a ; is not required either)


In fact, though:

Returns a bool true if all of the arguments compile (are 
semantically correct). The arguments can be symbols, types, or 
expressions that are syntactically correct. The arguments cannot 
be statements or declarations.

If there are no arguments, the result is false.

import std.stdio;

struct S
{
     static int s1;
     int s2;
}

int foo();
int bar();

void main()
{
     writeln(__traits(compiles));                      // false
     writeln(__traits(compiles, foo));                 // true
     writeln(__traits(compiles, foo + 1));             // true
     writeln(__traits(compiles, &foo + 1));            // false
     writeln(__traits(compiles, typeof(1)));           // true
     writeln(__traits(compiles, S.s1));                // true
     writeln(__traits(compiles, S.s3));                // false
     writeln(__traits(compiles, 1,2,3,int,long,std));  // true
     writeln(__traits(compiles, 3[1]));                // false
     writeln(__traits(compiles, 1,2,3,int,long,3[1])); // false


So ultimately it suggests a bug in the compiler.











More information about the Digitalmars-d-learn mailing list