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>.

Reply via email to