The original answer here had Foo<Bar> ill-formed, I actually now think it's well-formed. But ultimately, clang bug based.
I actually think even Foo<Bar> is ill-formed. The new rules, following P0522 are that:
A template-argument matches a template template-parameter P when P is at least as specialized as the template-argument A
where:
A template template-parameter P is at least as specialized as a template template-argument A if, given the following rewrite to two function templates, the function template corresponding to P is at least as specialized as the function template corresponding to A according to the partial ordering rules for function templates ([temp.func.order]). Given an invented class template X with the template parameter list of A (including default arguments):
- Each of the two function templates has the same template parameters, respectively, as
P or A.
- Each function template has a single function parameter whose type is a specialization of
X with template arguments corresponding to the template parameters from the respective function template where, for each template parameter PP in the template parameter list of the function template, a corresponding template argument AA is formed. If PP declares a parameter pack, then AA is the pack expansion PP... ([temp.variadic]); otherwise, AA is the id-expression PP.
If the rewrite produces an invalid type, then P is not at least as specialized as A.
Which means that to verify if Foo<Bar> itself is okay, we synthesize:
template <decltype(auto) I> struct X;
template <auto I> void __f(X<I> ); // P
template <decltype(auto) I> void __f(X<I> ); // A
All the types here are valid (so the last statement doesn't apply). Now, typically when we do partial ordering it's in the context of either overload resolution or picking a class template specialization, in which case what we're looking for is the "more specialized" function template, where F is more specialized than G if F is at least as specialized as G and G is not at least as specialized as F.
But in this context, we don't care about which is more specialized. We only need P to be at least as specialized as A. All that means that deduction has to succeed from A to P. So if we synthesize some unique type U with some value V, can we deduce X<I> from X<V>? Yes. Hence, P is at least as specialized as A, so the template-argument Bar matches the template-parameter TT.
Now, passing that point, I'd say this a clang bug. The template template-parameter is template <auto>, which is what we should use to validate the expression. With a non-type template parameter auto, we'd try to use x as a value - but x isn't a valid constant expression, so this should fail. clang appears to be using template <decltype(auto) > directly - which I'm not sure is valid.
That said, I'm not sure this case has even been considered - I don't see any wording one way or the other and it's worth raising an issue.