www.digitalmars.com         C & C++   DMDScript  
Archives

D Programming
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.ide
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger
D.gnu
D

C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows

digitalmars.empire
digitalmars.DMDScript
electronics


digitalmars.D.bugs - [Issue 3744] New: __traits getMember error in checking of second argument

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744

           Summary: __traits getMember error in checking of second
                    argument
           Product: D
           Version: 2.040
          Platform: x86_64
        OS/Version: Linux
            Status: NEW
          Severity: blocker
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: denis.tomilin gmail.com


--- Comment #0 from iorlas <denis.tomilin gmail.com> 2010-01-26 15:50:48 PST ---
Created an attachment (id=557)
Example code

I've trying to get text representation of class, that can be changed in
development time.
For this problem i've used __traits functions "allModules",
"isVirtualFunction"(for filtering) and "getMember" for getting a type by member
name(from "allModules").
But i've stuck in "getMember".

Error: string expected as second argument of __traits getMember instead of m

in
if (!__traits(isVirtualFunction, __traits(getMember, Check, m))){

Takes two arguments, the second must be a string.

Ofc, m is normal string. I've tried to use "writeln(typeid(typeof(m)));" for determinating a type of m-variable.
immutable(char)[]

But __traits still throws error. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 26 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744



--- Comment #1 from iorlas <denis.tomilin gmail.com> 2010-01-27 00:14:04 PST ---
I've tried to fix this problem and I've found this part of code, what can say
about this problem:
Object *o = (Object *)args->data[0];
Expression *e = isExpression((Object *)args->data[1]);
if (!e)
{   error("expression expected as second argument of __traits %s",
ident->toChars());
    goto Lfalse;
}
e = e->optimize(WANTvalue | WANTinterpret);
if (e->op != TOKstring)
{   error("string expected as second argument of __traits %s instead of %s =
%d", ident->toChars(), e->toChars(), e->op);
    goto Lfalse;
}

Problem in this code. This code want to see const string expression(every const string in the code). Program fails in this string:
if (e->op != TOKstring)

As i think, need to get an string from var and send it into StringExp instance for next operations, but i donts know how. Now i trying to find similar code in other sources. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 27 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au


--- Comment #2 from Don <clugdbug yahoo.com.au> 2010-01-27 00:53:18 PST ---
(In reply to comment #1)
 I've tried to fix this problem and I've found this part of code, what can say
 about this problem:
e = e->optimize(WANTvalue | WANTinterpret);
if (e->op != TOKstring)


 Problem in this code. This code want to see const string expression(every const
 string in the code). Program fails in this string:
if (e->op != TOKstring)

As i think, need to get an string from var and send it into StringExp instance for next operations, but i donts know how.

e->optimize(WANTvalue|WANTinterpret) should have turned it into a TOKstring. If it's still a TOKvar, then the problem is in e->optimize or earlier. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 27 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744



--- Comment #3 from iorlas <denis.tomilin gmail.com> 2010-01-27 01:41:07 PST ---
(In reply to comment #2)
 e->optimize(WANTvalue|WANTinterpret) should have turned it into a TOKstring. If
 it's still a TOKvar, then the problem is in e->optimize or earlier.

interesting, I dunno how can miss word "WANT" in "WANTvalue", but I did it +_+. Ok, good logic, but i cant find an implementation of this function. It must be predefined in expressions.h. And i found this:
struct VarExp : SymbolExp{
 ...
 Expression *optimize(int result);
 ...
}

But implementation there's in another file - optimize.c:
Expression *VarExp::optimize(int result)
{
    return fromConstInitializer(result, this);
}

This func found in this file:
Expression *fromConstInitializer(int result, Expression *e1)

original argument("this", with TOKvar):
e = expandVar(result, v);

Next...
Expression *expandVar(int result, VarDeclaration *v)
if (v->isConst() || v->isImmutable() || v->storage_class & STCmanifest)

But, stop! WTF? This function dont checks a WANTvalue flag and... i dunno. I want to cry.. really. I want to solve this problem cuz its blocked my work. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 27 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744



--- Comment #4 from Don <clugdbug yahoo.com.au> 2010-01-27 02:20:05 PST ---
Just had a look at your test code.
The problem lies here:

    foreach(string m; a){
        __traits(getMember, Check, m)
    }
m is not a compile-time constant. Of course it _should_ be, but it's not.

One thing you could try in traits.c is to replace:
e = e->optimize(WANTvalue);
with  e = e->interpret(NULL);
and that'll probably get it working.

But the real problem is in tuple foreach: the iteration variable should be a
compile-time constant.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 27 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744



--- Comment #5 from iorlas <denis.tomilin gmail.com> 2010-01-27 03:05:12 PST ---
(In reply to comment #4)
 Just had a look at your test code.
 The problem lies here:
 
     foreach(string m; a){
         __traits(getMember, Check, m)
     }
 m is not a compile-time constant. Of course it _should_ be, but it's not.

other) useless if it can't be used in runtime.
 One thing you could try in traits.c is to replace:
 e = e->optimize(WANTvalue);
 with  e = e->interpret(NULL);
 and that'll probably get it working.

from variable(typeid(typeof(__traits(getMember, Check, m)))), i've get always one string: fail.Check(). But if i try ti get this from Check.a, i've get a "int". I dunno why, cuz i think this is bad fix.
 But the real problem is in tuple foreach: the iteration variable should be a
 compile-time constant.

then perfectly compiles "hello world", lol. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 27 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744



--- Comment #6 from Don <clugdbug yahoo.com.au> 2010-01-28 11:09:25 PST ---
Actually, there's nothing at all wrong with __traits(getMember).
Really, you are asking for static foreach: given a compile-time constant array,
iterate over each of its members.
Since static foreach is unfortunately not going to happen (it was on Andrei's
list, but Walter rejected it), the other possibilities are to make
__traits(allMembers) into a tuple, or to use the static foreach workaround:

Something like:

enum a = __traits(allMembers, ...)'
foreach(T, int indx; ForEachTuple!(a.length))
{
   a = __traits(getMember, a[indx]);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 28 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744



--- Comment #7 from iorlas <denis.tomilin gmail.com> 2010-01-28 21:35:03 PST ---
(In reply to comment #6)
 Actually, there's nothing at all wrong with __traits(getMember).
 Really, you are asking for static foreach: given a compile-time constant array,
 iterate over each of its members.
 Since static foreach is unfortunately not going to happen (it was on Andrei's
 list, but Walter rejected it), the other possibilities are to make
 __traits(allMembers) into a tuple, or to use the static foreach workaround:
 
 Something like:
 
 enum a = __traits(allMembers, ...)'
 foreach(T, int indx; ForEachTuple!(a.length))
 {
    a = __traits(getMember, a[indx]);
 }

Ok, good idea. But i cannot find a "ForEachTuple" template. Static version of foreach might be help in this sitiation, but i dunno how to do it. Cuz if i use normal foreach with this hack(using enum and index for getting a name of member) a have one same error: Error: string expected as second argument of __traits getMember instead of a[indx]. =/ -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 28 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744



--- Comment #8 from iorlas <denis.tomilin gmail.com> 2010-02-02 14:40:11 PST ---
Maybe not a pure, but works(also, thx to eldar, qtd-developer):

template Alias(T...){ //small hack, cuz directly alias dont want to work
    alias T Alias;
}
alias Alias!(__traits(allMembers, abc)) ABCMEMBS; //alias creates data as
compile-time var
void main(){
    foreach(m;ABCMEMBS){ //now we can use it in compile-time
        writeln(m, ": ", typeid(typeof(__traits(getMember, abc, m)))); //all
ok, cuz it's in compile-time
    }
}

class abc{
    void foo(){
    }
    int a,b,c;
}

We have this output:
foo: void()
a: int
b: int
c: int

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 02 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744


iorlas <denis.tomilin gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P2                          |P4
            Version|2.040                       |2.041
           Severity|blocker                     |minor


--- Comment #9 from iorlas <denis.tomilin gmail.com> 2010-02-02 14:43:13 PST ---
Changed priority, cuz now i can use one way to solve my problem. See code in
prev msg.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 02 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3744


Hoenir <mrmocool gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mrmocool gmx.de


--- Comment #10 from Hoenir <mrmocool gmx.de> 2010-02-04 20:00:15 PST ---
This is correlated with that bug:
http://d.puremagic.com/issues/show_bug.cgi?id=1386

Interestingly it still doesn't work even though allMembers returns a tuple
since r360:

4: foreach(m; __traits(allMembers, Check)){
5:    if (!__traits(isVirtualFunction, __traits(getMember, Check, m))){
6:        writefln("Var: s%, Type: %s", m, typeid(typeof(m)));
    }
}

yields:

main.d(5): Error: 'this' is only defined in non-static member functions, not
main
main.d(5): Error: this for a needs to be type Check not type int

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 04 2010