https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71843
Bug ID: 71843 Summary: [concepts] Diagnostics issued for constraint satisfaction failure fail to elucidate unsatisfied constraints Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tom at honermann dot net CC: andrew.n.sutton at gmail dot com, asutton at gcc dot gnu.org Target Milestone: --- The diagnostics emitted when overload resolution fails due to constraint satisfaction failure do not elucidate the constraints that were not satisfied. For non-trivial concepts, it can be difficult and tedious for a user to determine exactly why a given type did not satisfy a set of constraints. For example, using gcc 6.1.0: $ cat t.cpp template<typename T> concept bool C = requires(T t) { t.i; }; template<C T> auto f(T t) { return t.i; } struct S { }; auto x = f(S{}); $ g++ --version g++ (GCC) 6.1.0 ... $ g++ -c -std=c++1z -fconcepts t.cpp t.cpp:9:15: error: cannot call function ‘auto f(T) [with T = S]’ auto x = f(S{}); ^ t.cpp:4:6: note: constraints not satisfied auto f(T t) { ^ t.cpp:4:6: note: concept ‘C<S>’ was not satisfied The error message clearly indicates that S does not satisfy the constraints associated with concept C, but does not explain that the reason constraint satisfaction failed is because the expression t.i is ill-formed for an object t of type S. When designing types intended to model a particular concept, it is often useful to statically assert that the type models the intended concept. Here too the error messages are less helpful then desired: $ cat t2.cpp template<typename T> concept bool C = requires(T t) { t.i; }; struct S { }; static_assert(C<S>); $ g++ -c -std=c++1z -fconcepts t2.cpp t2.cpp:5:1: error: static assertion failed static_assert(C<S>); ^~~~~~~~~~~~~