On Thursday, 26 June 2014 at 10:09:53 UTC, Rene Zwanenburg wrote:
I /think/ this is a bug, but I'm not 100% sure. The following
compiles without any problems, as it should:
import std.typecons;
alias Handle(T) = RefCounted!(T, RefCountedAutoInitialize.no);
auto initialized(T)() if(is(T == RefCounted!S, S...))
{
T refCounted;
refCounted.refCountedStore.ensureInitialized();
return refCounted;
}
alias S = Handle!S_Impl;
struct S_Impl
{
}
void main()
{
auto s = initialized!S;
}
Change 'initialized' to:
auto initialized(T)() if(is(T == Handle!S, S))
and the compiler will complain:
Error: template instance test.initialized!(RefCounted!(S_Impl,
cast(RefCountedAutoInitialize)0)) does not match template
declaration initialized(T)() if (is(T == Handle!S, S))
I don't think that's a bug, but I think the template constraint
itself shouldn't be legal to write. It's not possible to support
the general case of a template A in is(T == A!X, X) as it would
require following all possible instantiation paths of A.
The compiler could keep track of how a type was created on a
per-identifier basis and then use that to check, but that would
mean rejecting types that had a different instantiation path
(e.g. is(RefCounted!(int, RefCountedAutoInitialize.no) ==
Handle!S, S) == false).
What might be feasible would be to extend is(T == A!X, X) to work
with simple tmeplates and paramterised aliases like Handle, while
statically disallowing more complicated / undecidable ones..