Thread overview
Strange template alias behaviour
Nov 18, 2012
Jack Applegame
Nov 18, 2012
Maxim Fomin
Nov 18, 2012
Simen Kjaeraas
November 18, 2012
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.
November 18, 2012
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.
November 18, 2012
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