cplusplus / CWG

Core Working Group
23 stars 7 forks source link

CWG2911 [expr.prim.req.general] Unclear meaning of expressions "appearing within" versus subexpressions #562

Open hubert-reinterpretcast opened 1 week ago

hubert-reinterpretcast commented 1 week ago

Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong

Reference (section label): expr.prim.req.general

Link to reflector thread (if any): N/A

Issue description: According to https://wg21.link/expr.prim.req.general#2:

Expressions appearing within a requirement-body are unevaluated operands

It is clearly meant to not encompass, e.g., constant-expression‌s, appearing within the requirement-body but the unfriendly reading is possible.

It is also unclear what this means, e.g., with respect to expressions that appear within a requirement-body as part of the body of a lambda expression.

For example, does x in the lambda below refer to a const int capture? Implementations agree that it does.

void q(int *);
int &q(const int *);

template <typename T>
constexpr bool f() {
  T x;
  constexpr bool v = requires {
    [=] { ++q(&x); };
  };
  return v;
}

static_assert(f<int>());  // OK

Suggested resolution: Strike in https://wg21.link/expr.prim.req.general#2:

A requires-expression is a prvalue of type bool whose value is described below. Expressions appearing within a requirement-body are unevaluated operands.

Modify in https://wg21.link/expr.prim.req.simple#1:

A simple-requirement asserts the validity of an expression. The expression is an unevaluated operand ([expr.context]). [Note: The enclosing requires-expression will evaluate to false if substitution of template arguments into the expression fails. The expression is an unevaluated operand ([expr.context]).end note]

Modify in https://wg21.link/expr.prim.req.compound#1:

A compound-requirement asserts properties of the expression E. The expression is an unevaluated operand ([expr.context]). [...]

Modify in https://wg21.link/expr.context#1:

In some contexts, unevaluated operands appear ([expr.prim.req], [expr.prim.req.simple], [expr.prim.req.compound], [expr.typeid], [expr.sizeof], [expr.unary.noexcept], [dcl.type.decltype], [temp.pre], [temp.concept]). An unevaluated operand is not evaluated.

jensmaurer commented 1 week ago

CWG2911