This question is based on Andrei's answer to my question on signature constraints.
struct S(int x, int y) {
void fun(T)(T t) if (is(T U == S!(a, b), int a, int b)) { }
}
template s(int a, int b) {
enum result = S!(a,b)();
alias result s;
}
void main() {
auto s1 = S!(1, 1)();
auto s2 = S!(2, 2)();
auto s3 = s!(3, 3);
auto s4 = s!(4, 4);
s1.fun(s1); // ok
s1.fun(s2); // ok
s1.fun(s3); // compile error
s3.fun(s1); // ok
s3.fun(s3); // compile error
s3.fun(s4); // compile error
}
I don't understand why the code is producing compile errors. Any ideas?
First, I wouldn't recommend using a naked template to generate an instance of an object/struct, because you're essentially requiring the object to be CTFE-able. If you need an instance your best option is to return
it from a templated function:
@property S!(a, b) s(int a, int b)()
{
return S!(a, b)();
}
However this still doesn't seem to work with the template constraint. I think this has to be a front-end bug. From what I can tell it seems that the type returned cannot be properly checked in the is() expression unless it was already instantiated somewhere else, e.g.:
struct S(int x, int y)
{
void fun(T)(T t)
if (is(T U == S!(a, b), int a, int b))
{
}
}
@property S!(a, b) s(int a, int b)()
{
return S!(a, b)();
}
void main()
{
auto s1 = S!(1, 1)();
auto s2 = S!(2, 2)(); // comment out and you get errors in fun() call
auto s3 = s!(2, 2);
s1.fun(s3);
}
I'll file this as a bug.
Edit: Filed as Issue 8493.