Skip to content

CWG2517 [expr.prim.req.nested] Unnecessary restriction on local parameter use in nested requirements #183

@brevzin

Description

@brevzin

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions