--- template TypeTuple(TList...) { alias TList TypeTuple; } void main() { foreach(T; TypeTuple!(shared void*, const shared void*)) { static if (is(T U == shared const U)) alias U TU; else static if (is(T U == shared U)) alias U TU; else static assert(0); pragma(msg, "T: ", T, "\nTU: ", TU, "\n"); static if(is(T P == P*)) static if(is(TU PU == PU*)) static assert(is(P == PU)); // fails on second iteration T t; bool b = is(typeof(cast(TU*) &t = null)); // comment to hide a bug } } --- Output: --- T: shared(void*) TU: shared(void)* T: shared(const(void*)) TU: shared(void)* main.d(16): Error: static assert (is(shared(const(void)) == shared(void))) is false --- Second `TU` should be `shared(const(void))*`. As always, such (unexpected) template bugs are hard to figure out.
Works for me since DMD 2.065. The assert doesn't fail anymore, and the second `TU` is `shared(const(void))*` now.