Comment #0 by andrej.mitrovich — 2013-09-24T16:04:30Z
-----
module test;
int glob;
struct K
{
@property void max(int) { }
@disable @property ref int max() { return glob; }
alias setMax = _chainerFunc!max;
template _chainerFunc(alias symbol)
{
import std.traits;
alias Params = ParameterTypeTuple!symbol;
auto ref _chainerFunc(Params[0] args) // ok
{
symbol = args;
return this;
}
}
}
struct F
{
@property void max(int) { }
@disable @property ref int max() { return glob; }
alias setMax = _chainerFunc!max;
template _chainerFunc(alias symbol)
{
import std.traits;
alias Params = ParameterTypeTuple!symbol;
auto ref _chainerFunc(Params args) // fail
{
symbol = args; // Error: attempts to call getter
return this;
}
}
}
void main()
{
K k;
k.max = 2;
k.setMax(1).setMax(2); // chaining example
F f;
f.max = 2;
f.setMax(1).setMax(2); // ditto
}
-----
$ dmd test.d
fail.d(39): Error: function test.F.max is not callable because it is annotated with @disable
fail.d(39): Error: cannot implicitly convert expression (tuple(_param_0)) of type (int) to int
The code in "main()" is not needed but demonstrates the usage. Note how the compiler wants to call the wrong @property function (the getter instead of the setter).
The above hurts generic code having to use Params[0] when the length is already known to equal 1.
-- Please note: The bug goes away if there is no getter property, but only a @property setter is available. Observe:
-----
module test;
struct K
{
@property void max(int) { }
// commented out
// @property int max() { return 1; }
alias setMax = _chainerFunc!max;
template _chainerFunc(alias symbol)
{
import std.traits;
alias Params = ParameterTypeTuple!symbol;
// ok, now works without Params[0]
auto ref _chainerFunc(Params args)
{
symbol = args;
return this;
}
}
}
void main()
{
K k;
k.max = 2;
k.setMax(1).setMax(2); // chaining example
}
-----
So I think this is a bug, and not an enhancement.
Comment #1 by robert.schadek — 2024-12-13T18:12:04Z