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.