I found what I believe is a bug in the way that Dlang deals with template mixins containing properties.
The short story is: if you split the getter and setter between two mixin templates, and if the got/set thing is a class (presumably it would work for a struct too), and you try to retrieve a member of that class (or struct) you get the error:
no property '???' for type 'void'
where '???' is the name of the member you attempted to access.
It's hard to explain, but here is my example below:
class Box { uint value = 5; }
mixin template tempy1()
{
public @property void points (Box p)
{
this._points = p;
}
// }
// mixin template tempy2()
// {
public @property Box points ()
{
return this._points;
}
}
class Foo
{
private Box _points;
mixin tempy1;
// mixin tempy2;
unittest { assert((new Foo()).points.value == 5); }
}
Pardon the compression. With all of the comments in place, this compiles just fine, but remove all of the comments, and you'll see the error message described above. Note, again, that this problem only occurs when the get/set thing is a class (again, maybe a struct too).
Maybe there is a little quirk about properties that I have missed, but I reviewed the documentation on properties, and it does not seem like this should happen. Strangely, it seems like removing the setter makes the above compile, even without the comments.
Comment #1 by jonathan — 2017-12-16T19:03:15Z
Sorry, I just remembered to provide version info:
uname -a
Darwin <REDACTED HOSTNAME> 17.3.0 Darwin Kernel Version 17.3.0: Thu Nov 9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64 x86_64
dmd --version
DMD64 D Compiler v2.077.0
Copyright (c) 1999-2017 by Digital Mars written by Walter Bright
ld -v
@(#)PROGRAM:ld PROJECT:ld64-274.1
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
LTO support using: LLVM version 8.0.0, (clang-800.0.38)
TAPI support using: Apple TAPI version 1.30
Comment #2 by nick — 2022-09-05T17:39:14Z
The error should be improved, but this should not compile. From the spec:
> If two different mixins are put in the same scope, and each define a declaration with the same name, there is an ambiguity error when the declaration is referenced
https://dlang.org/spec/template-mixin.html#mixin_scope
This is to prevent accidental collisions. Instead, you can do this inside class Foo:
mixin tempy1 t1;
mixin tempy2 t2;
alias points = t1.points;
alias points = t2.points;
Comment #3 by robert.schadek — 2024-12-13T18:55:34Z