Fallback 'catch-all' template functions
Timon Gehr via Digitalmars-d
digitalmars-d at puremagic.com
Thu Sep 1 11:24:13 PDT 2016
On 01.09.2016 19:55, Meta wrote:
> On Thursday, 1 September 2016 at 17:49:13 UTC, Timon Gehr wrote:
>> On 01.09.2016 19:21, Meta wrote:
>>> ...
>>>
>>> I just thought of this, but cannot test if it works. If it does, maybe
>>> it would be a suitable solution?
>>>
>>> void f(T)(T t) if(isSomething!T) {}
>>> void f(T)(T t) if(isSomethingElse!T) {}
>>> //Taken if no other "overload" of f will intantiate with the given T
>>> void f(T)(T t) if(!__traits(compiles, alias _ = .f!T)) {}
>>
>> It shouldn't work, but DMD currently seems to allow it. (If you fix
>> the syntax error.) I would expect it to break later.
>>
>>
>> The following causes an ICE (DMD segfaults).
>>
>> import std.stdio;
>>
>> int f(T)(T t) if(!__traits(compiles,.f!T)) {
>> return 0;
>> }
>> int f(T)(T t) if(!__traits(compiles,.f!T)) {
>> return 1;
>> }
>>
>> void main(){
>> writeln(f(2));
>> }
>
> 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.
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.
More information about the Digitalmars-d
mailing list