If you mix in getters and setters in seperate template mixins, it fails to compile on first property-like usage. Strangely, you may use both overloads if you treat them like functions (e.g. the first examples in main below). I think this is related to http://d.puremagic.com/issues/show_bug.cgi?id=1686 and http://d.puremagic.com/issues/show_bug.cgi?id=9235. Offending code: mixin template Getter() { @property auto x() { return _x; } } mixin template Setter() { @property void x(int x) { _x = x; } } struct Foo { int _x; mixin Getter!(); // definition order is irrelevant mixin Setter!(); } void main() { auto f = Foo(4); auto x1 = f.x(); //fine f.x(2); // fine auto x2 = f.x; // Error: expression has no value f.x = 3; // Error: f.x is not an lvalue }
https://github.com/D-Programming-Language/dmd/pull/2047
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/e892946b376b8365bc6cefd896e5e3e6a1219b16 fix Issue 10103 - template mixin with property overloads https://github.com/D-Programming-Language/dmd/commit/fa4a52c8e832f43081349332ea3d274d976c54ca Merge pull request #2047 from 9rnsr/fix10103 Issue 10103 - template mixin with property overloads
Commit pushed to 2.063 at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/76d09dfa5ef28176f666aa6f50038ed6a48b830b Fix 2.063 branch breaking Bug10103 is not yet fixed in 2.063 branch.
Commit pushed to 2.063 at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/76d09dfa5ef28176f666aa6f50038ed6a48b830b Fix 2.063 branch breaking
Created attachment 1281 [details] Alternative example of problem The problem does not appear to be resolved in all cases. See attached code, where a class takes _one_ of the implementations (getter _or_ setter) via a mixin, and the other is local.
Created attachment 1282 [details] Second example of bug still in existence This second example has the _getter_ obtained via mixin, while the setter is in the class itself.
The current fix does not cover all possible cases. The two recently-attached examples show cases where, of a getter/setter property pair, a class implements one of them locally and obtains the other via a mixin. In both cases errors result: $ rdmd mixproperty.d mixproperty.d(30): Error: a.foo is not an lvalue $ rdmd mixproperty2.d mixproperty2.d(31): Error: function mixproperty2.A.foo (const(int) f) is not callable using argument types ()
(In reply to comment #7) > The current fix does not cover all possible cases. The two recently-attached > examples show cases where, of a getter/setter property pair, a class implements > one of them locally and obtains the other via a mixin. In both cases errors > result: > > $ rdmd mixproperty.d > mixproperty.d(30): Error: a.foo is not an lvalue > > $ rdmd mixproperty2.d > mixproperty2.d(31): Error: function mixproperty2.A.foo (const(int) f) is > not callable using argument types () No. The two cases does not work as you expected. **It's by design**. mixin template B() { void foo(int n) {} } class C { void foo() {} // Mixed-in symbol foo(int) won't be automatically merged with foo(). // In other words, C.foo() hides C.B!().foo(int) normally. mixin B; } void main() { auto c = new C; c.foo(); // OK c.foo(1); // NG, foo() is not callable using argument types (int) } If you want to make workable both c.foo() and c.foo(1), you need to change the mixin declaration as follows. class C { ... mixin B x; alias foo = x.foo; // merge foo(int) in the overload set 'C.foo' } void main() { auto c = new C; c.foo(); // OK c.foo(1); // OK } I know that currently D does not have a feature to do it automatically. If you want to do it, you could design a language enhancement to resolve the issue. Change back the issue status.
Thanks for the explanation, Kenji -- apologies for the misunderstanding, but at least we now have this special case documented here :-)