digitalmars.D - [BUG, with testcase] problem with type system, __traits accross static libraries
- "Lloyd Dupont" <ld-REMOVE galador.net> Jun 24 2011
- "Lloyd Dupont" <ld-REMOVE galador.net> Jun 24 2011
- "Lloyd Dupont" <ld-REMOVE galador.net> Jun 24 2011
It's going to be long as I'm going to post all the code...
Basically there is a bug in the type system or __traits when the program is
split in static lib and exe (as opposed to all in one).
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
====================================
Jun 24 2011
In plain English what I am trying to do:
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)
because the field name are going to be a parameter there is a bit of
convolution and mixin and template.
anyway...
Apparently I just recieved a response "it's not a bug" (it's a feature)
because
-------
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.
I don't even understand how the answer relate to my problem, nor how to
solve it!
Can any one explain to (in plain understandable English) why is it a
feature, and, most importantly, how to work around it!?!?
Jun 24 2011
Apparently it's not a bug, it's feature (I can't begin to fathom why)
At any rate, by replacing
writeln(mixin( "__traits(compiles, t." ~memberName ~" = ("
~typeof(__traits(getMember, T, memberName)).stringof ~").init)" ));
with
writeln(mixin( "__traits(compiles, t." ~memberName ~" = (typeof(t."
~memberName ~")).init)" ));
it works as expected!
Jun 24 2011









"Lloyd Dupont" <ld-REMOVE galador.net> 