www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - bug in compiles?

reply Alex <AJ gmail.com> writes:
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?

T is a local variable name passed to this code, which does 
generally return an
error when used in certain ways:


int x;

Code!x; // Basically the code at the top

if I try to do too much with x I get `cannot use local `x` as a 
parameter to a non-global template`. Usually when I try to pass T 
to another template I get this error.


But some things work. But I can't for the life of me understand 
why compiles is failing but the foreach loop is working.


The problem is that I am using compiles quite often and either 
I'm misusing it or it's got some bugs in it that worry me because 
maybe they are silently failing?

Note that I get no errors in my code and I do get the attributes 
so it is technically working.

It would be really nice to know why the compiles is failing, e.g.,

pragma(compilesmsg, __traits(getAttributes, T)) spits out the 
error.
Apr 11
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/11/19 2:13 PM, 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?
It should. Do you have a larger example? One that can be played with? -Steve
Apr 11
parent reply Alex <AJ gmail.com> writes:
On Thursday, 11 April 2019 at 19:42:05 UTC, Steven Schveighoffer 
wrote:
 On 4/11/19 2:13 PM, 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?
It should. Do you have a larger example? One that can be played with? -Steve
import std.stdio, std.traits, std.conv; struct A(alias T) { static void foo() { static if (__traits(compiles, __traits(getAttributes, T))) // Failing for some reason static foreach(a; __traits(getAttributes, T)) pragma(msg, to!string(a), "-", typeof(a).stringof); } } void main() { (3) int a; (A!a).foo(); } Commenting out the static if allows the foreach to pass and everything works. The whole point of the static if is to let the foreach work. Both are only dependent on __traits(getAttributes, T) So if that can't compile then how could the foreach work? https://run.dlang.io/is/WlXCIZ
Apr 11
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/11/19 6:45 PM, Alex wrote:
 On Thursday, 11 April 2019 at 19:42:05 UTC, Steven Schveighoffer wrote:
 On 4/11/19 2:13 PM, 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?
It should. Do you have a larger example? One that can be played with? -Steve
import std.stdio, std.traits, std.conv; struct A(alias T) {     static void foo()     {         static if (__traits(compiles, __traits(getAttributes, T))) // Failing for some reason             static foreach(a;  __traits(getAttributes, T)) pragma(msg, to!string(a), "-", typeof(a).stringof);     } } void main() {     (3) int a;     (A!a).foo(); } Commenting out the static if allows the foreach to pass and everything works. The whole point of the static if is to let the foreach work. Both are only dependent on __traits(getAttributes, T) So if that can't compile then how could the foreach work? https://run.dlang.io/is/WlXCIZ
Seems like a bug to me. These all work: (3) int a; static assert(__traits(compiles, __traits(getAttributes, a))); alias X = a; static assert(__traits(compiles, __traits(getAttributes, X))); But this does not: static function foo(alias T)() { static assert(__traits(compiles, __traits(getAttributes, T))); } foo!a; I think all 3 should work. -Steve
Apr 11
prev sibling next sibling parent reply bauss <jj_1337 live.dk> writes:
On Thursday, 11 April 2019 at 18:13:48 UTC, 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?

 T is a local variable name passed to this code, which does 
 generally return an
 error when used in certain ways:


 int x;

 Code!x; // Basically the code at the top

 if I try to do too much with x I get `cannot use local `x` as a 
 parameter to a non-global template`. Usually when I try to pass 
 T to another template I get this error.


 But some things work. But I can't for the life of me understand 
 why compiles is failing but the foreach loop is working.


 The problem is that I am using compiles quite often and either 
 I'm misusing it or it's got some bugs in it that worry me 
 because maybe they are silently failing?

 Note that I get no errors in my code and I do get the 
 attributes so it is technically working.

 It would be really nice to know why the compiles is failing, 
 e.g.,

 pragma(compilesmsg, __traits(getAttributes, T)) spits out the 
 error.
Must be something else in your code because it works fine for me with this shortened example. https://run.dlang.io/is/o8xESB
Apr 11
parent reply Alex <AJ gmail.com> writes:
On Thursday, 11 April 2019 at 20:49:45 UTC, bauss wrote:
 On Thursday, 11 April 2019 at 18:13:48 UTC, 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?

 T is a local variable name passed to this code, which does 
 generally return an
 error when used in certain ways:


 int x;

 Code!x; // Basically the code at the top

 if I try to do too much with x I get `cannot use local `x` as 
 a parameter to a non-global template`. Usually when I try to 
 pass T to another template I get this error.


 But some things work. But I can't for the life of me 
 understand why compiles is failing but the foreach loop is 
 working.


 The problem is that I am using compiles quite often and either 
 I'm misusing it or it's got some bugs in it that worry me 
 because maybe they are silently failing?

 Note that I get no errors in my code and I do get the 
 attributes so it is technically working.

 It would be really nice to know why the compiles is failing, 
 e.g.,

 pragma(compilesmsg, __traits(getAttributes, T)) spits out the 
 error.
Must be something else in your code because it works fine for me with this shortened example. https://run.dlang.io/is/o8xESB
Seriously? Do you think you have ESP? Your code isn't even close to was talking about ;/ Here is is updated that shows the error. You seem to fail to understand that it is impossible for it to be my code. There is no way the static if should fail yet the static foreach pass. They both go together, that is is the whole point of the static if, to make sure the foreach works, yet it says it doesn't work when it in fact does(as commenting out the line proves). import std.stdio, std.traits, std.conv; struct A(alias T) { static void foo() { static if (__traits(compiles, __traits(getAttributes, T))) // Failing for some reason static foreach(a; __traits(getAttributes, T)) pragma(msg, to!string(a), "-", typeof(a).stringof); } } void main() { (3) int a; (A!a).foo(); }
Apr 11
parent reply Mike Parker <aldacron gmail.com> writes:
On Thursday, 11 April 2019 at 22:41:32 UTC, Alex wrote:

 Seriously? Do you think you have ESP? Your code isn't even 
 close to was talking about ;/

 Here is is updated that shows the error. You seem to fail to 
 understand that it is impossible for it to be my code.
If you continue to attack people who are trying to help you, the moderators will stop approving your posts. The hostility is unwelcome here. If the number of your posts that have not been approved didn’t serve as a warning, then this does.
Apr 11
parent reply Alex <AJ gmail.com> writes:
On Thursday, 11 April 2019 at 23:04:46 UTC, Mike Parker wrote:
 On Thursday, 11 April 2019 at 22:41:32 UTC, Alex wrote:

 Seriously? Do you think you have ESP? Your code isn't even 
 close to was talking about ;/

 Here is is updated that shows the error. You seem to fail to 
 understand that it is impossible for it to be my code.
If you continue to attack people who are trying to help you, the moderators will stop approving your posts. The hostility is unwelcome here. If the number of your posts that have not been approved didn’t serve as a warning, then this does.
Quick google search to help you with your problem: https://www.quora.com/How-do-I-develop-a-thick-skin-and-stop-getting-offended-over-everything https://www.arkansasonline.com/news/2019/feb/05/too-thin-skin-20190205/ https://medium.com/the-mission/welcome-to-the-thin-skinned-generation-where-everything-is-a-bloody-problem-8bd5cb336361 http://dare.wisc.edu/survey-results/1965-1970/emotional-states-and-attitudes/gg8 http://meanttobehappy.com/10-ways-you-too-can-stop-being-so-easily-offended/ You can't police the world. You seem to live in a PC fantasy world where where every little booboo is treated as a life and death situation. You are not helping with the world with your need to control it. What are you going to do when things get really bad in the world? Have a nervous break down? If you think the shit I say is hostile and attacking people you really have no clue what the real world is like. You seem to have control issues that you should get addressed if you are going to threaten people over moronic statements that you interpret with your bias to be hostile. I'm sorry, but I'm not going to play your games. Did you go after FeepingCreature? He was clearly more hostile than I was but I bet you didn't say a god damn thing to him... You want me to stop being "hostile" then you need to throw your badge in the trash and stop trying to police every conversation because you really are in no position to judge people objectively. This isn't a nursery school and we are not 3 year olds... and if you want to turn it in to that kinda atmosphere then you kiss my ass.
Apr 11
parent Seb <seb wilzba.ch> writes:
On Thursday, 11 April 2019 at 23:55:18 UTC, Alex wrote:

 to judge people objectively. This isn't a nursery school and we 
 are not 3 year olds...
Exactly. So start behaving like a grown-up and professional. When you ask someone for help on the street, do you curse at him too?
Apr 11
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
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 -- /Jacob Carlborg
Apr 12
next sibling parent Alex <AJ gmail.com> writes:
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.
Apr 12
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/12/19 5:43 AM, Jacob Carlborg wrote:

 The problem is that "__traits(getAttributes, T)" in it self is not valid 
 code. It needs to be part of larger expression or statement.
It does work, as long as it's not an alias passed into a template: void main() { (3) int a; static assert(__traits(compiles, __traits(getAttributes, a))); // OK alias b = a; static assert(__traits(compiles, __traits(getAttributes, b))); // OK static void foo(alias c)() { static assert(__traits(compiles, __traits(getAttributes, c))); // Error } foo!a(); } It seems like a straight-up bug to me. I don't see the difference between those 3 calls. -Steve
Apr 12