https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94862
Bug ID: 94862
Summary: [concepts] Extraneous/wrong template parameters
printed in diagnostic
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: ppalka at gcc dot gnu.org
Target Milestone: ---
$ cat testcase.C
template<typename R>
struct remove_reference
{ using type = R; };
template<typename T>
using remove_reference_t = remove_reference<T>::type;
template<typename T>
inline constexpr bool blah = false;
template<typename T>
requires blah<remove_reference_t<T>>
void foo(remove_reference_t<T> = {}) { }
void bar() { foo<int> (); }
$ g++ -std=c++2a testcase.C
testcase.C: In function ‘void bar()’:
testcase.C:15:24: error: use of function ‘void foo(remove_reference_t<T>) [with
T = int; remove_reference_t<T> = int]’ with unsatisfied constraints
15 | void bar() { foo<int> (); }
| ^
testcase.C:13:8: note: declared here
13 | void foo(remove_reference_t<T> = {}) { }
| ^~~
testcase.C:13:8: note: constraints not satisfied
testcase.C: In instantiation of ‘void foo(remove_reference_t<T>) [with T = int;
remove_reference_t<T> = int]’:
testcase.C:15:24: required from here
testcase.C:13:8: required by the constraints of ‘template<class T> requires
blah<typename remove_reference<R>::type> void foo(remove_reference_t<T>)’
testcase.C:12:12: note: the expression ‘blah<typename
remove_reference<R>::type> [with R = int; T = int]’ evaluated to ‘false’
12 | requires blah<remove_reference_t<T>>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
We pretty print the constraint
blah<remove_reference_t<T>>
with the alias template specialization stripped:
blah<typename remove_reference<R>::type>
but doing so introduces the unrelated template parameter 'R' from the
definition of the alias template remove_reference.
So it seems it would be better to not strip alias template specializations when
pretty printing constraints. It would also be more consistent, since we don't
strip them when printing e.g. function parameter types.