Skip to content

Improve diagnostic when concept doesn't match because required operation is private #158902

@RedBeard0531

Description

@RedBeard0531

Consider the easy mistake of forgetting to put public: at the top of a class:

class AlmostPred {
    void operator()(int) const;
};

void f(std::predicate<int> auto p) {}

When you try to invoke f you get a very confusing error that stops with: because 'is_invocable_v<AlmostPred, int>' evaluated to false. If you don't already know the problem, it can be very frustrating to see that error because the operator() with identical arguments is RIGHT THERE 😡. At least I was recently frustrated by debugging this. Compare that to the gcc trunk output which tells you exactly what is wrong and letting you click to go right to the place to fix it.

          • 'AlmostPred' is not invocable by 'int', because
          • error: 'void AlmostPred::operator()(int) const' is private within this context
          • declared private here
            <source>:6:10:
                6 |     void operator()(int) const;
                  |          ^~~~~~~~

Clang does a bit better when you use requires expressions directly in the function declaration rather than concepts (even though the general advice is to never do that and to always use named concepts instead). With void g(auto p) requires(requires(int i) {p(i);}){} the error ends with because 'p(i)' would be invalid: 'operator()' is a private member of 'AlmostPred'. This could be improved further by including a reference to the declaration of the private member and possibly even a fixit to add public: to the top of the class (probably only if there are no protection markers in the class and it is just using the default).

Either way, the message about the function being private should be shown when attempting to use a concept. Really any concept failure should include the root cause of the failure, even if it skips a few steps between the named concept and the root cause by default for brevity.

clang trunk godbolt with both f and g
clang trunk with libc++ (no better)
gcc trunk godbolt

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:diagnosticsNew/improved warning or error message in Clang, but not in clang-tidy or static analyzerconceptsC++20 concepts

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions