On 01.09.2016 21:02, Meta wrote:
On Thursday, 1 September 2016 at 18:24:13 UTC, Timon Gehr wrote:
The idea is that there'd only be one such "fallback" template, so that
you cannot get into a situation such as this. I'm guessing the ICE is
due to a recursive dependency between the two f templates?
I posted the ICE to show that DMD does not necessarily have a clear
concept of how your code should be interpreted. Note that you are
essentially saying: "If not X then X". It's very easy to run into
behaviour that seems inconsistent once you do things like this.
Well, I'd argue that's not quite right and the correct interpretation is
"If not the other X then this X", due to the `!__traits(compiles,
.f!T)`, explicitly telling the compiler to check if the *other*
"overloads" compile.
Even if that was the intention of the compiler implementation, the
example below demonstrates why it cannot work.
I don't actually know whether template constraints
are considered to be at module scope or in the template scope, though,
so maybe I'm completely wrong on this.
...
Template scope, but /nothing/ about '.' says "other".
enum isSomething(T)=false;
int f(T)(T t) if(isSomething!T){
return 0;
}
int f(T)(T t) if(!compiles!".f!int") {
return 2;
}
enum compiles(string s) = __traits(compiles,mixin(s));
pragma(msg, compiles!".f!int"); // false
pragma(msg, __traits(compiles,.f!int)); // true
DMD cannot properly process code like this (i.e. code that contradicts
itself, where the same expression in the same context can be true in
one part of the compilation, but false later). Examples can be
constructed where the semantics of the resulting code depends on the
order that modules are passed on the command line. It's not specified
anywhere what should happen, and it is not immediately clear.
DMD shouldn't accept code like this in the first place. It's very
brittle, the result depends on random compiler implementation details.
I would argue that this is an entirely different case than my example,
but we are getting into compiler implementation details that I know
nothing about, so I can't actually say whether it is (or should) be
valid code.
It's basically the same thing.