#dbugfix Issue 16486 200$

Simen Kjærås simen.kjaras at gmail.com
Sat Mar 31 16:34:14 UTC 2018


On Saturday, 31 March 2018 at 13:34:18 UTC, Kagamin wrote:
> On Friday, 30 March 2018 at 13:56:45 UTC, Stefan Koch wrote:
>> Ah that is an interesting bug which further demonstrates that 
>> templates are a tricky thing :)
>> Basically you cannot _generally_ proof that one template just 
>> forwards to another.
>> Therefore you have to create separate types.
>> And since you create separate types the alias is not an alias 
>> but a separate template.
>> Solving this may be possible for special cases but in the 
>> general case is infeasible.
>
> If a template is used as a type it should be resolved to a 
> type, no? And template resolves to a type in a straightforward 
> way. Where does it fail? Judging by the error message "cannot 
> deduce function from argument types !()(TestType!int)" it does 
> successfully resolve alias to a type.

You're starting in the wrong end - the type cannot yet be 
considered, since the compiler doesn't know the correct arguments 
to TestAlias. Given this code:

struct S(T...) {}
alias SS(T...) = S!(T, int);

void foo(T)(SS!T arg) {}

unittest {
     foo(SS!string());
}

The error message is "template foo cannot deduce function from 
argument types !()(S!(string, int)), candidates are: foo(T)(SS!T 
arg)".

What the compiler needs to do is figure out what T needs to be in 
order for SS to return the type S!(int, int). SS hasn't resolved 
to a type yet at that point, because the compiler has no idea 
which arguments to give it.

These are the steps the compiler does when it evaluates a 
function call (simplified):

1) Figure out the overload set.
2) Weed out non-matching overloads.
3) Check that exactly one overload matches*.
4) Use that overload.

In step 2, the compiler looks at the types when the overload is a 
regular function. When it's a function template, it doesn't know 
the types yet, and IFTI tries to figure it out by a sort of 
pattern matching. In the case above, it doesn't find a 
S!(/*something*/) anywhere, and gives up.

If the compiler were to do something other than give up, we would 
need some algorithm to define what it should try, and in which 
order. As human beings, with impressive collections of 
pattern-matching circuits, we can easily see that it should try 
putting the first template argument into T. Getting to that 
conclusion is a lot harder for the poor, stupid compiler.

--
   Simen


*In the case where multiple overloads are a match, the best fit 
is chosen. If there's more than one best fit, or there's no 
match, you get a compile error.


More information about the Digitalmars-d mailing list