I don't have time to respond to all your points right now :) But here are a few thoughts.
Depends which of the several C++ meanings for “specialization” you intend . That's why I am using the word “concretization” instead to refer to a Swift generic type or function with all of its generic parameters replaced by concrete types.
I'm talking about the opposite. I'm talking about a full specialization. Or an overloaded definition of a class template.
Unconditional extensions should apply to all concretizations. Conditional extensions should apply according to their conditions.
This might be the most reasonable way to implement this. But it makes less sense when the full "specialization" (not concretization) is an entirely different type than the "templated version". (For example, X<int>
vs X<void>
.)
I imagine we'll want to be able to write a conformance of std::vector to Sequence for all Ts, don't you?
Yeah, I didn't do a good job describing what I mean. When we have a full specialization of a class template with a different definition, you would be forced to extend that type explicitly. So for the example (with struct A
) A<char>
would get extended with extension A: Y {}
so would A<Foo>
and A<std::vector<int>>
but A<int>
would not because it has a fully "specialized" (or overloaded) definition.
So extension std::vector : Sequence
would mean std::vector
would always be a Sequence
(oops... well... not std::vector<bool>
)
I assume "normal Swift type-checking" means phase one type-checking? Without the logic above, how can this be type-checked during phase one? We can't know if T = Void
until after specialization has happened. Am I missing something?
If we apply the above logic, though, this could become a phase one error. Because if T == Void
is true, then the extension won't apply so X == XManualModel
is false. And I don't think it's unreasonable to ask that each fully specialized (or overloaded) class template definition must be explicitly extended.