Closed
Description
Repro: https://godbolt.org/z/rn8e3GP6c
template <class> constexpr int A = 1;
template <int> struct B;
template <> struct B<1> { using b1 = void; };
template <class> using C = char;
template <class... Ds> int D{ B<A<C<Ds>>>{}... };
The pattern contains an unexpanded pack, but it's just syntatic.
We incorrectly don't convert the expression, leaving it as a instantiation dependent DeclRef, and then
incorrectly specialize the primary template for B
.
This is diagnosed with:
<source>:8:31: error: implicit instantiation of undefined template 'B<A<C<Ds>>>'
template <class... Ds> int D{ B<A<C<Ds>>>{}... };
^
<source>:3:23: note: template is declared here
template <int> struct B;
^
<source>:8:44: error: pack expansion does not contain any unexpanded parameter packs
template <class... Ds> int D{ B<A<C<Ds>>>{}... };
With recent changes (https://reviews.llvm.org/D136564) regarding sugared substitution of default template arguments, we would start misdiagnosing this snippet as well (continued from above):
struct E {
template <class E1, class = typename B<A<E1>>::b1> E(E1);
};
template <typename... Es> int F{ E(C<Es>{})... };
And this is diagnosed with:
<source>:14:34: error: no matching conversion for functional-style cast from 'C<Es>' (aka 'char') to 'E'
template <typename... Es> int F{ E(C<Es>{})... };
^~~~~~~~~
<source>:10:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'C<Es>' (aka 'char') to 'const E' for 1st argument
struct E {
^
<source>:10:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'C<Es>' (aka 'char') to 'E' for 1st argument
struct E {
^
<source>:11:54: note: candidate template ignored: substitution failure [with E1 = C<Es>]: implicit instantiation of undefined template 'B<A<C<Ds>>>'
template <class E1, class = typename B<A<E1>>::b1> E(E1);