September 08, 2011
I'm working for fixing issue 6208
(http://d.puremagic.com/issues/show_bug.cgi?id=6208).
I found a funny behavior in template function deduction.

// from std.array.replaceSlice
void replaceSlice(T)(T[] s, in T[] slice, in T[] replacement) {}  // 1
//void replaceSlice(T)(T[] s, const(T[]) slice, const(T[]) replacement) {}  // 2
void main()
{
    string s;
    replaceSlice(s, s, s);  // should complile
}

With current dmd (git master: 3da0a366), #1 can compile, but #2 fails. But, #1 and #2 have just same meanings, so both should compile.

The cause lies in template.c Type::deduceType().
The type deduction process of #2 is like follows:
1. With the 1st parameter `s', T[] vs immutable(char)[]
  -> T vs immutable(char)
  -> T is deduced with immutable(char)
2. With the 2nd parameter `slice', const(T[]) vs immutable(char)[]
  -> const(T) vs immutable(char)
  -> T is deduced with char --> conflict!

Then, we should select *most common type* for that deduction.
...
2. With the 2nd parameter `slice', const(T[]) vs immutable(char)[]
  -> const(T) vs immutable(char)
  -> T is deduced with char
  -> T == CommonType(immutable(char), char) == const(char)
Finally, T is deduced with const(char).

I think this deduction process is naturally introduced D's transitive
type system.
(Even if it is different from C++ type deduction. I don't know more about that.)
And as far as I know, it is *necessary* for proper inout type with
template function.
(see https://github.com/D-Programming-Language/dmd/pull/359)

Walter, do you have any comments?

Kenji Hara