https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117294
Bug ID: 117294 Summary: Concept swallow diagnostics when they're defined in terms of type traits Product: gcc Version: 14.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: barry.revzin at gmail dot com Target Milestone: --- Here's a simple, broken program: #include <concepts> template <std::default_initializable T> auto make() { T t; return t; } struct A { explicit A(int) {} }; template <typename T> struct Foo { T a = 1; }; auto tryit() { return make<Foo<A>>(); } This (correctly) fails to compile, and the compile message does tell me A isn't default constructible. Which... is okay (this is on -fconcepts-diagnostics-depth=10, there's no more information than this): <source>:19:24: error: no matching function for call to 'make<Foo<A> >()' 19 | return make<Foo<A>>(); | ~~~~~~~~~~~~^~ <source>:4:6: note: candidate: 'template<class T> requires default_initializable<T> auto make()' 4 | auto make() { | ^~~~ <source>:4:6: note: template argument deduction/substitution failed: <source>:4:6: note: constraints not satisfied In file included from <source>:1: /modules/rhel8/gcc-14.1.0/include/c++/14.1.0/concepts: In substitution of 'template<class T> requires default_initializable<T> auto make() [with T = Foo<A>]': <source>:19:24: required from here 19 | return make<Foo<A>>(); | ~~~~~~~~~~~~^~ /modules/rhel8/gcc-14.1.0/include/c++/14.1.0/concepts:159:13: required for the satisfaction of 'constructible_from<_Tp>' [with _Tp = Foo<A>] /modules/rhel8/gcc-14.1.0/include/c++/14.1.0/concepts:164:13: required for the satisfaction of 'default_initializable<T>' [with T = Foo<A>] /modules/rhel8/gcc-14.1.0/include/c++/14.1.0/concepts:160:30: note: the expression 'is_constructible_v<_Tp, _Args ...> [with _Tp = Foo<A>; _Args = {}]' evaluated to 'false' 160 | = destructible<_Tp> && is_constructible_v<_Tp, _Args...>; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On the other hand, if instead of using the concept std::default_initializeable, I just wrote "class T"... the body of make<T> will fail to instantiate in a different way. And the error that I get is overwhelmingly better: <source>: In instantiation of 'constexpr Foo<A>::Foo()': <source>:9:7: required from 'auto make() [with T = Foo<A>]' 9 | T t; | ^ <source>:23:24: required from here 23 | return make<Foo<A>>(); | ~~~~~~~~~~~~^~ <source>:19:11: error: could not convert '1' from 'int' to 'A' 19 | T a = 1; | ^ | | | int It would be really nice if concepts diagnostics were still able to tell me __why__ something fails instead of just that it does. Demo on compiler explorer: https://compiler-explorer.coredev.jt/z/cd6YYM