C++ function template specialization and generic functions in Swift

I understand. What I'm saying is that I'm not sure there exists a C++ template that can sensibly be imported as a Swift generic. The properties of Swift generics are just very different from those of C++ templates, and thinking of them as one thing (and especially representing them as one thing in the compiler) may not make sense.

“Clang gives us an error” is part of phase 2 type checking.

I misunderstood what a second type-checking phase meant. If it means "check that the argument types still match and propagate any Clang errors," I'm 100% on board.

Propagating Clang errors may be required, but I'm not thinking of phase 2 typechecking as being exclusively about clang errors. There's still a valuable role for Swift's type checker to play in phase 2.

Yeah, I'm pretty sure that approach isn't going to work out well. For one thing, get_a_type might just as easily have been defined like this:

template<class> struct get_a_type;
template<> struct get_a_type<int> { using type = has_the_thing<T>; };

Now caller2 fails to compile because the compiler doesn't even have a general definition of get_a_type, but when actually called with Int.self it ought to work.

Secondly, Swift's overload resolution happens during phase 1 type-checking. That's a feature-not-a-bug that makes Swift generics more predictable than C++ templates. I don't think we want to introduce overload resolution into phase 2 of Swift if we can help it. Of course it's unavoidable on the C++ side.

This brings up another question. In Swift the idea of type specializations doesn't really exist.

Depends which of the several C++ meanings for “specialization” you intend :wink:. 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.

So, when we import a specialization of a type, does that count as the "same" type or a different one?

It acts like the same generic type but applies to one or more concretizations (multiple if it is a partial specialization). This is analogous to the way a conditional extension or conformance applies to one or more concretizations of a Swift generic.

And should extensions apply to both types, or only one?

Unconditional extensions should apply to all concretizations. Conditional extensions should apply according to their conditions.

If we say that extensions must be applied to a specific type specialization, then we could probably make this a "phase one" error which would be nice.

Yes, full specializations of C++ templates are always type-checked in phase 1 (even in C++), because they are concrete types.

Since you asked… to me it seems like an unnecessary limitation that would make programming verbose and tedious. I imagine we'll want to be able to write a conformance of std::vector<T> to Sequence for all Ts, don't you? If you're asking about it as a short-term step toward full interoperability, though, I say again, “whatever works!” :wink:

Speaking of specializations, from this thread I conclude that Swift generics eventually need to gain similar expressive power to C++ templates. One of the issues raised there is that non-monomorphizability would force some ambiguities to be resolved at runtime in such a world. Now that we're talking seriously about bringing C++ templates into Swift, and with it, forced monomorphization, it's probably worth asking if there's a way to unify the solutions to these two issues. Maybe there's a way to force monomorphization of just the pieces of Swift that would be needed to resolve/report the ambiguities. And if we get that far, maybe thinking of C++ templates as being imported as Swift generics does make sense after all.