https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97572
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> --- The diagnostic is different now and the "cannot convert 'T' to 'bool'" part is gone. For comment 0 we get: 97572.C: In substitution of 'template<class auto:1> requires Any<auto:1> constexpr int f(auto:1) [with auto:1 = bool]': 97572.C:4:22: required from here 97572.C:2:63: error: 't' is not a constant expression 2 | template <typename T> concept Any = requires (T t) { requires any (t); }; | ~~~~~~~~~^~~~~~~ 97572.C:4:22: error: no matching function for call to 'f(bool)' 4 | constexpr auto q = f (false); | ~~^~~~~~~ 97572.C:3:22: note: candidate: 'template<class auto:1> requires Any<auto:1> constexpr int f(auto:1)' 3 | constexpr static int f (Any auto) { return 42; }; | ^ 97572.C:3:22: note: substitution of deduced template arguments resulted in errors seen above This seems good enough to me. It tells you that 't' is not a constant expression, which is correct, and that means that the call any(t) is not a constant expression and so can't be used as the operand to 'requires'. Because that constraint fails, it means that you can't call f(Any auto), and so there is not matching function. I still think it might be helpful to say that local parameters of a requires-expression are never constant expressions. For comment 2 we get: 97572-c2.C:2:63: error: 't' is not a constant expression 2 | template <typename T> concept Any = requires (T t) { requires any (t); }; | ~~~~~~~~~^~~~~~~ 97572-c2.C:3:16: error: static assertion failed 3 | static_assert (Any <bool>); | ^~~~~~~~~~ 97572-c2.C:3:16: note: constraints not satisfied 97572-c2.C:2:31: required by the constraints of 'template<class T> concept Any' 97572-c2.C:2:37: in requirements with 'T t' [with T = bool] 97572-c2.C:2:63: error: 't' is not a constant expression 2 | template <typename T> concept Any = requires (T t) { requires any (t); }; | ~~~~~~~~~^~~~~~~ 97572-c2.C:2:63: error: 't' is not a constant expression Again, this seems good enough. (In reply to Dimitri Gorokhovik from comment #4) > -- arguably, a close contender is "error: âtâ is not a constant expression". But it's absolutely correct. > Understanding how it can happen was hard to me. 't' looks as constant as > they get with requires-local-parameters (I mean, constexpr-ness of a > local-parameter here should be understood as coming only from its > declaration shouldn't it?). Yes, and function parameters are *never* constant expressions, even in consteval functions. Why do you think it would be different here? constexpr int f(int n) { static_assert(n!=1); } ce.C:1:41: error: ânâ is not a constant expression It's constexpr-ness *does* come from its declaration, and it's not declared as a constant. > The (S s) form of requires-local-var is a common > form, so when the compiler says 's' is not a constant expression' here, how > would it be constant in other situations? By using ... a constant of course. e.g. a literal like 1 or true, or a constant like std::is_integral_v<T>.