https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106285
Bug ID: 106285 Summary: Reduce visual noise and confusing grouping when printing overload candidate errors Product: gcc Version: unknown Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- This is the same code as PR 106256: template<class A, class B> class C { public: C() = default; template<class AA, class BB> C(AA, BB) { } C(C&&) = default; private: struct __secret_tag { }; template<class AA, class BB> C(AA&, BB&, __secret_tag) { } }; C<int, int> c({}, {}); We get these errors: cons.C:20:21: error: no matching function for call to ‘C<int, int>::C(<brace-enclosed initializer list>, <brace-enclosed initializer list>)’ 20 | C<int, int> c({}, {}); | ^ cons.C:16:5: note: candidate: ‘template<class AA, class BB> C<A, B>::C(AA&, BB&, __secret_tag) [with BB = AA; A = int; B = int]’ 16 | C(AA&, BB&, __secret_tag) | ^ cons.C:16:5: note: template argument deduction/substitution failed: cons.C:20:21: note: candidate expects 3 arguments, 2 provided 20 | C<int, int> c({}, {}); | ^ cons.C:8:5: note: candidate: ‘template<class AA, class BB> C<A, B>::C(AA, BB) [with BB = AA; A = int; B = int]’ 8 | C(AA, BB) | ^ cons.C:8:5: note: template argument deduction/substitution failed: cons.C:20:21: note: couldn’t deduce template parameter ‘AA’ 20 | C<int, int> c({}, {}); | ^ cons.C:11:3: note: candidate: ‘constexpr C<A, B>::C(C<A, B>&&) [with A = int; B = int]’ 11 | C(C&&) = default; | ^ cons.C:11:3: note: candidate expects 1 argument, 2 provided cons.C:5:3: note: candidate: ‘constexpr C<A, B>::C() [with A = int; B = int]’ 5 | C() = default; | ^ cons.C:5:3: note: candidate expects 0 arguments, 2 provided Why do the first and second candidates repeat the caller location: 20 | C<int, int> c({}, {}); | ^ We've already shown that once with the "no matching function for call to ..." error at the top. Why are we repeating it? Isn't it just noise that makes the candidate list harder to read? Secondly, currently we show the candidate, then its declaration, then the reason it's not viable: cons.C:5:3: note: candidate: ‘constexpr C<A, B>::C() [with A = int; B = int]’ 5 | C() = default; | ^ cons.C:5:3: note: candidate expects 0 arguments, 2 provided However, when that's in the middle of a long list of candidates, it's hard to see where each new candidate begins. The two related notes are separated by the caret diagnostic. Would it make more sense to group the reason with the candidate, i.e.: cons.C:5:3: note: candidate: ‘constexpr C<A, B>::C() [with A = int; B = int]’ cons.C:5:3: note: candidate expects 0 arguments, 2 provided 5 | C() = default; | ^ If we combine these suggestions (remove repeated caret showing call site, and putting the decl caret after the failure reason, and the PR 106281 ordering change) I think the result is much better: cons.C:20:21: error: no matching function for call to ‘C<int, int>::C(<brace-enclosed initializer list>, <brace-enclosed initializer list>)’ 20 | C<int, int> c({}, {}); | ^ cons.C:8:5: note: candidate: ‘template<class AA, class BB> C<A, B>::C(AA, BB) [with BB = AA; A = int; B = int]’ cons.C:8:5: note: template argument deduction/substitution failed: cons.C:20:21: note: couldn’t deduce template parameter ‘AA’ 8 | C(AA, BB) | ^ cons.C:11:3: note: candidate: ‘constexpr C<A, B>::C(C<A, B>&&) [with A = int; B = int]’ cons.C:11:3: note: candidate expects 1 argument, 2 provided 11 | C(C&&) = default; | ^ cons.C:5:3: note: candidate: ‘constexpr C<A, B>::C() [with A = int; B = int]’ cons.C:5:3: note: candidate expects 0 arguments, 2 provided 5 | C() = default; | ^ cons.C:16:5: note: candidate: ‘template<class AA, class BB> C<A, B>::C(AA&, BB&, __secret_tag) [with BB = AA; A = int; B = int]’ cons.C:16:5: note: template argument deduction/substitution failed: cons.C:20:21: note: candidate expects 3 arguments, 2 provided 16 | C(AA&, BB&, __secret_tag) | ^