www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Strange template alias behaviour

reply "Jack Applegame" <japplegame gmail.com> writes:
I wrote about strange thing here 
http://forum.dlang.org/thread/xftbyifuuubxhhsolgpv forum.dlang.org
And now another very strange thing appears when we pass mixin 
identifier as template alias parameter.
Look at this code:

import std.stdio;

mixin template Foo() {
   char[] data = "default".dup;
}

class Bar {
   char[] data;
   mixin Foo F1;
   mixin Foo F2;
}

void check_data(alias M, T)(T obj) {
   assert(obj.data == "Bar");
   assert(obj.F1.data == "F1");
   assert(obj.F2.data == "F2");
}

void main() {
   Bar bar = new Bar;

   bar.data = "Bar".dup;
   bar.F1.data = "F1".dup;
   bar.F2.data = "F2".dup;

   assert(bar.data == "Bar");
   assert(bar.F1.data == "F1");
   assert(bar.F2.data == "F2");

   check_data!(bar)(bar);
}

Everything works ok, no assertions.
But after changing "check_data!(bar)(bar)" to 
"check_data!(Bar.F1)(bar)" or "check_data!(Bar.F2)(bar)", you 
will get assertions.
Seems like bug.
Nov 18 2012
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
Reduced:

import std.stdio;

mixin template Foo() {
   string data = "default";
}

class Bar {
   string data;
   mixin Foo f;
}

void check_data(alias M, T)(T obj) {
   writeln(M.stringof);
   writeln(obj.data);
   writeln(obj.f.data);
}

void main() {
   Bar bar = new Bar;
   bar.data = "Bar";
   bar.f.data = "F";

   writeln(bar.data);
   writeln(bar.f.data);

   check_data!(Bar)(bar);
}

Changing template parameter to Bar.f or bar.f affects value of 
bar.f.data. Seems to be a bug.
Nov 18 2012
parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On 2012-05-18 17:11, Maxim Fomin <maxim maxim-fomin.ru> wrote:

 Changing template parameter to Bar.f or bar.f affects value of  
 bar.f.data. Seems to be a bug.
It's a bug. Further reduction: import std.stdio; mixin template Foo() { string data = "default"; } struct Bar { mixin Foo f; } string get_data(alias unused, T)(T obj) { return obj.f.data; } void main() { Bar bar = Bar(""); writeln(get_data!Bar(bar)); writeln(get_data!(Bar.f)(bar)); // This line fucks things up. assert( get_data!Bar(bar) == get_data!(Bar.f)(bar) ); } Note also that moving the marked line above the line before it makes the assert pass. However, the writelns will both print the wrong value ("default"). -- Simen
Nov 18 2012