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.