A requires-expression similarly to a function can introduce local parameters using a parameter list. And lambda expressions defined at block scope may have captures without initializers. Is it allowed to capture local parameters of requires-expression?
Consider the example:
template<typename T>
concept C = requires( T t ) {
[t]{ [t]{}; };
};
which is accepted by both GCC and MSVC. And only Clang complains (demo: https://gcc.godbolt.org/z/o17hWGabG) here:
error: constraint variable 't' cannot be used in an evaluated context
As far as I understand [t]{ [t]{}; };
is a simple requirement, where the expression is an unevaluated operand; only language correctness is checked.
What is the expected behavior of a compiler here?
From expr.prim.req.general#2 (my emphasis):
A requires-expression is a prvalue of type
bool
whose value is described below. Expressions appearing within a requirement-body are unevaluated operands.
where "requirement-body" refers to the { … }
part.
So Clang is complaining incorrectly, I believe.
Furthermore, this discussion on llvm-project seems to support my understanding. I suspect you're are the one who reported it there too, by the way.
user17732522's point below is that
[t]{ [t]{}; };
is an expression that appears within the requirement-body of a requires-expression and, as such, it is indeed an unevaluated operand;
however, as per basic#intro.execution-note-1,
Expressions appearing in the compound-statement of a lambda-expression are not subexpressions of the lambda-expression.
and [t]{}
is therefore not a subexpression of [t]{ [t]{}; };
, so it does not automatically inherit the property of being unevaluated;
I'm not sure from where, however, I should deduce that it is indeed evaluated, though. On the other hand, the issue user17732522 points to suggests that the wording is indeed confusing.