Clang currently rejects the following code:
template <typename X>
constexpr bool is_valid = true;
template<typename T>
class Nesting
{
public:
template<typename Q> requires is_valid<Q>
class Inner;
};
template<typename T>
template<typename Q> requires is_valid<Q>
class Nesting<T>::Inner
{
public:
static inline void Do();
};
#include <iostream>
template<typename T>
template<typename Q> requires is_valid<Q>
inline void Nesting<T>::Inner<Q>::Do()
{
std::cout << sizeof(T);
}
int main() {
Nesting<int>::Inner<bool>::Do();
}
with
<source>:14:31: error: requires clause differs in template redeclaration
14 | template<typename Q> requires is_valid<Q>
| ^
<source>:8:35: note: previous template declaration is here
8 | template<typename Q> requires is_valid<Q>
| ^
<source>:25:35: error: out-of-line definition of 'Do' from class 'Inner<Q>' without definition
25 | inline void Nesting<T>::Inner<Q>::Do()
| ~~~~~~~~~~~~~~~~~~~~~~^
<source>:31:19: error: implicit instantiation of undefined template 'Nesting<int>::Inner<bool>'
31 | Nesting<int>::Inner<bool>::Do();
| ^
<source>:9:11: note: template is declared here
9 | class Inner;
What is wrong with my code - is it a clang bug?
LLVM team confirms that this is a compiler bug: see https://github.com/llvm/llvm-project/issues/145521