Thread overview
[Issue 6211] New: __traits (compile) return wrong result when the bug happen
Jun 25, 2011
Lloyd Dupont
Jun 25, 2011
Vladimir Panteleev
Jun 25, 2011
Lloyd Dupont
Jun 25, 2011
Lloyd Dupont
Jun 25, 2011
Vladimir Panteleev
Jun 25, 2011
Lloyd Dupont
Jul 11, 2011
Kenji Hara
June 25, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6211

           Summary: __traits (compile) return wrong result when the bug
                    happen
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: ld@galador.net


--- Comment #0 from Lloyd Dupont <ld@galador.net> 2011-06-24 18:30:57 PDT ---
I'm using DMD2.053 on Windows7 x64

My test case:
- I have a all in one console application which output "true true"
- I have a project with the exact same code split into a static lib and an
exe and it output "false false"

The bug is that the output is different!

=== first the all in one, outputing "true, true" ========= module main;

import std.variant;
import std.stdio;
import std.metastrings : Format;
import std.traits;

public mixin template property(T, string name)
{
    mixin(Format!("private T _%s;
                  @property public T %s() { return _%s; }
                  @property public void %s(T value) { _%s = value; }", name,
name, name, name, name));
}

interface IInter
{
}

class Foo : IInter
{
    static this()
    {
        Compiled!(Foo, "FP");
        Compiled!(Foo, "Subfoo");
    }

    @property public Foo FP() { return new Foo(); }
    @property public void FP(Foo f) { }

    mixin property!(Foo, "Subfoo");
}

int main(string[] argv)
{
    return 0;
}
void Compiled(T, string memberName)()
{
    T t;
    writeln(mixin( "__traits(compiles, t." ~memberName ~" = ("
~typeof(__traits(getMember, T, memberName)).stringof  ~").init)" ));
}
==============================================


now the splitted program, outputting "false, false"
whereas it should output "true, true" just like above, shouldn't it!?!

===== lib.d ====
module lib;

import std.variant;
import std.stdio;
import std.metastrings : Format;
import std.traits;

public mixin template property(T, string name)
{
    mixin(Format!("private T _%s;
                  @property public T %s() { return _%s; }
                  @property public void %s(T value) { _%s = value; }", name,
name, name, name, name));
}

interface IInter
{
}

void Compiled(T, string memberName)()
{
    T t;
    writeln(mixin( "__traits(compiles, t." ~memberName ~" = "
~typeof(__traits(getMember, T, memberName)).stringof  ~").init" ));
}
====== main.d =====
module main;

import lib;

class Foo : IInter
{
    static this()
    {
        Compiled!(Foo, "FP");
        Compiled!(Foo, "Subfoo");
    }

    @property public Foo FP() { return new Foo(); }
    @property public void FP(Foo f) { }

    mixin property!(Foo, "Subfoo");
}

int main(string[] argv)
{
    return 0;
}
===================== buildrun.bat =========
dmd -lib -g -debug -X -of"lib1.lib" lib.d
dmd -g -debug -X main.d lib1.lib
main
====================================

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 25, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6211


Vladimir Panteleev <thecybershadow@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |thecybershadow@gmail.com
         Resolution|                            |INVALID


--- Comment #1 from Vladimir Panteleev <thecybershadow@gmail.com> 2011-06-24 18:38:13 PDT ---
This is not a bug. See section "Instantiation Scope" of http://www.d-programming-language.org/template.html .

> TemplateInstantances are always performed in the scope of where the TemplateDeclaration is declared, with the addition of the template parameters being declared as aliases for their deduced types.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 25, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6211



--- Comment #2 from Lloyd Dupont <ld@galador.net> 2011-06-24 19:03:57 PDT ---
How does the template scope has anything to do with this bug?

In plain English I'm testing that the property can be set.
I.e.
class Foo
{
 @property public Foo Subfoo() {}

 @property public Foo Subfoo2() {}
 @property public void Subfoo2(Foo f) {}
}

in the above class Subfoo can't be set, Subfoo2 can.
I'm testing it with
Foo f,
__traits(compile, f.Suboo = Foo.init)
__traits(compile, f.Suboo2 = Foo.init)

This seems to work erratically!

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 25, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6211



--- Comment #3 from Lloyd Dupont <ld@galador.net> 2011-06-24 20:24:36 PDT ---
Not understanding the explanation I can't claim it wrong...

Nonetheless the work around I found seems to indicate to me that the explanation was, at the very least (for what I understand) completely irrelevant.

I replaced:
writeln(mixin( "__traits(compiles, t." ~memberName ~" =
("~typeof(__traits(getMember, T, memberName)).stringof  ~").init)" ));


With:
writeln(mixin( "__traits(compiles, t." ~memberName ~" = (typeof(t."~memberName
~")).init)" ));


And it worked. Still using library and exe.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 25, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6211


Vladimir Panteleev <thecybershadow@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |


--- Comment #4 from Vladimir Panteleev <thecybershadow@gmail.com> 2011-06-24 20:29:43 PDT ---
Sorry, it looked like you were instantiating a template in a scope where a symbol passed by name as a string didn't exist. You may want to reduce your example to the smallest amount of code which illustrates the bug for clarity.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 25, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6211



--- Comment #5 from Lloyd Dupont <ld@galador.net> 2011-06-24 21:01:19 PDT ---
I found a way to reduce the sample even further.

1st no need to have 2 project (lib & exe). All in the same exe (but different
module) is enough to cause the bug.

==== main.d ====
module main;

import lib;

class Foo
{
    static this()
    {
        Compiled!(Foo, "Subfoo");
    }

    @property public Foo Subfoo() { return null; }
    @property public void Subfoo(Foo f) { }
}

int main(string[] argv)
{
    return 0;
}
====== lib.d ======
module lib;

import std.traits;
import std.stdio;

void Compiled(T, string memberName)()
{
    T t;
    writeln(mixin( "__traits(compiles, t." ~memberName ~" = ("
~typeof(__traits(getMember, T, memberName)).stringof  ~").init)" ));
}
===============

this output "false", whereas it should output "true"

a work around (and simpler code in fact) is to use the following simpler mixin
(in Compiled)
---
writeln(mixin( "__traits(compiles, t." ~memberName ~" = (typeof(t." ~memberName
~")).init)" ));
---

Yet I do think this sample highlight a compiler bug

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 11, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6211


Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
                 CC|                            |k.hara.pg@gmail.com
         Resolution|                            |INVALID


--- Comment #6 from Kenji Hara <k.hara.pg@gmail.com> 2011-07-11 01:24:01 PDT ---
This is not bug.
In lib.d, you can't access Foo by name (without importing main).

---- lib.d ----
void Compiled(T, string memberName)()
{
    T t;      // ok
    Foo foo;  // error!
}
----

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