On 04.01.21 15:44, Ola Fosheim Grøstad wrote:
On Monday, 4 January 2021 at 14:40:31 UTC, ag0aep6g wrote:
You didn't replace "Bar!int" with "Foo!int". You replaced "Bar!T" with
"Foo!T". That's something else entirely.
No, it isn't.
Of course it is. Replacing foo with bar is not the same as replacing baz
with qux. The resulting code is different. The compiler output is different.
My original post stands.
When it is instantiated you get "Bar!int" and then the
unification would substitute that with "Foo!int".
In `f(Bar!int());`, `Bar!int` is expanded to `Foo!int` before IFTI is
attempted. When `f` is instantiated, any mention of `Bar` is long
forgotten. The compiler sees the argument type as `Foo!int` (the type,
not the string "Foo!int"). From there it deduces `T` = `int` when the
parameter is `Foo!T x`, or it fails the instantiation when the parameter
is `Bar!T x`. Either way, there's no "Bar!int" anymore that would be
replaced by anything.
This is basic type system design. Nothing advanced. Just plain regular
unification.
As far as I understand, describing what DMD does as "unification" would
be a stretch. You might have a point saying that DMD should do "plain
regular unification" instead of the ad hoc, undocumented hacks it does
right now.