cat > bug.d << CODE
struct Vector(T, int N)
{
void opDispatch(string, U)(U)
{
}
}
struct Matrix(T, int R, int C)
{
Matrix!(T, R, U._C) opBinary(string op, U)(U)
// this constraint causes a compile error (even though the first test already fails)
if (is(typeof(U._isMatrix)) && (U._R == C) && (op == "*"))
{
return Matrix!(T, R, U._C)();
}
Vector!(T, R) opBinary(string op)(Vector!(T, C) x)
{
return Vector!(T, R)();
}
enum _R = R;
enum _C = C;
enum bool _isMatrix = true;
}
unittest
{
Matrix!(int, 2, 2) z;
auto z2 = z * z; // works
static assert(!is(typeof(Vector!(int, 2)._isMatrix)));
z * Vector!(int, 2)(); // errors on template constraint
}
CODE
dmd -c -unittest bug
----
math/gfm/math/matrix.d(11): Error: void has no value
math/gfm/math/matrix.d(11): Error: incompatible types for ((opDispatch!"_R") == (2)): 'void' and 'int'
----
There is something broken w/ the evaluation of template constraints.
if (is(typeof(U._isMatrix)) && (U._R == C) && (op == "*"))
In here the IsExp is already false, so the rest shouldn't get evaluated.
Comment #1 by code — 2016-01-16T17:46:50Z
The bug boils down to this behavior change.
cat > bug.d << CODE
struct Vector(T, int N)
{
void opDispatch(string, U)(U)
{
}
}
static assert(!is(typeof(Vector!(int, 2)._isMatrix)));
CODE
dmd -c -o- bug
----
bug.d(9): Error: static assert (!true) is false
----
It works w/ 2.069.2.
- Still happen in DMD 2.071-b
- Can't reproduce on Windows
FWIW I could change the code, but I don't seem to find a workaround. I've tried std.traits.hasMember instead and it fails similarly.
Comment #5 by aliloko — 2016-01-19T22:32:24Z
Found a work-around.
Comment #6 by github-bugzilla — 2016-01-27T12:36:43Z