-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Reference (section label): [expr.prim.req.nested]
Link to reflector thread (if any): https://lists.isocpp.org/core/2019/06/6579.php
Issue description: [expr.prim.req.nested]/2 currently reads:
A local parameter shall only appear as an unevaluated operand within the constraint-expression.
This restriction isn't necessary. We already need to require that the constraint-expression is actually a constant expression. That could still be true even if the expression uses a local parameter - as long as none of the other [expr.const] rules are violated. The restriction is also inconsistent with other uses of constraints. For example:
struct S {
static constexpr bool test() { return true; }
};
template <class T>
concept Test =
requires (const T t) {
requires t.test(); // error: this is not allowed
};
static_assert(Test<S>);
template <typename T>
constexpr int f(T t) requires (t.test()) { // all compilers: ok
return 1;
}
static_assert(f(S{}) == 1); // all compilers: ok
Even though the definition of Test
violates [expr.prim.req.nested]/2, both gcc and msvc allow it anyway with the expected meaning. Only Clang actually implements this rule today (but doesn't diagnose it at the point of Test
's definition, only when it's evaluated).
Suggested resolution: Strike [expr.prim.nested.req]2.