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