On Monday, 4 January 2021 at 15:31:02 UTC, ag0aep6g wrote:
On 04.01.21 16:03, jmh530 wrote:
IMO, this is a better example, even if it's a little more verbose.

struct Foo(T) {}

alias Bar(T) = Foo!T;

void f(T)(Bar!T x) {}

void main() {
     auto x = Bar!int();
     f(x);
}

To be sure that I'm not missing anything: You just added the temporary `x`, right? I don't think that changes anything. The type of the argument is `Foo!int` in all variations of the code we've seen, including this one. And that type is all that DMD sees when it attempts IFTI of `f`.

Ah, I see your point above now (mixing up my Bar!ints and Bar!Ts). Yes, that was the only change and not really a substantive change (just my ease of reading).

Your point is basically that a template alias only becomes an actual alias when it has been instantiated. You then note that the deduction process operates in terms of Bar (in that you have to find a T that fits Bar!T to get to an alias of Foo!T). I think part of what is confusing is that the temporary x in my example is a Foo!int and not a Bar!int, which is why the Foo!int can't be passed into f(T)(Bar!T).

I think part of the issue is that many people's mental model would be for f(T)(Bar!T) to get re-writtn as f(T)(Foo!T), which is related to Ola's point with respect to type unification.

But the compiler isn't really doing any re-writing, so much as it sees the Foo!int and does not have the information necessary to determine that a Foo!int should satisfy Bar!T (as you point out). It would need to extract int from Foo!int, then instantiate Bar!T to get Foo!int (which I believe is what the implementation was doing, or something similar).

Reply via email to