This patch uses the nested diagnostics capabilities added in the earlier
patch in the C++ frontend.
With this, and enabling the non-standard text formatting via:
-fdiagnostics-set-output=text:experimental-nesting=yes
and using:
-std=c++20 -fconcepts-diagnostics-depth=2
then the output for the example in SG15's P3358R0 ("SARIF for Structured
Diagnostics") is:
P3358R0.C: In function ‘int main()’:
P3358R0.C:26:6: error: no matching function for call to ‘pet(lizard)’
26 | pet(lizard{});
| ~~~^~~~~~~~~~
• note: candidate: ‘template<class auto:1> requires pettable<auto:1> void pet(auto:1)’
P3358R0.C:21:6:
21 | void pet(pettable auto t);
| ^~~
• note: template argument deduction/substitution failed:
• note: constraints not satisfied
• P3358R0.C: In substitution of ‘template<class auto:1> requires pettable<auto:1> void pet(auto:1) [with auto:1 = lizard]’:
• required from here
P3358R0.C:26:6:
26 | pet(lizard{});
| ~~~^~~~~~~~~~
• required for the satisfaction of ‘pettable<auto:1>’ [with auto:1 = lizard]
P3358R0.C:19:9:
19 | concept pettable = has_member_pet<T> or has_default_pet<T>;
| ^~~~~~~~
• note: no operand of the disjunction is satisfied
P3358R0.C:19:38:
19 | concept pettable = has_member_pet<T> or has_default_pet<T>;
| ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
• note: the operand ‘has_member_pet<T>’ is unsatisfied because
P3358R0.C:19:20:
19 | concept pettable = has_member_pet<T> or has_default_pet<T>;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
• required for the satisfaction of ‘has_member_pet<T>’ [with T = lizard]
P3358R0.C:13:9:
13 | concept has_member_pet = requires(T t) { t.pet(); };
| ^~~~~~~~~~~~~~
• required for the satisfaction of ‘pettable<auto:1>’ [with auto:1 = lizard]
P3358R0.C:19:9:
19 | concept pettable = has_member_pet<T> or has_default_pet<T>;
| ^~~~~~~~
• in requirements with ‘T t’ [with T = lizard]
P3358R0.C:13:26:
13 | concept has_member_pet = requires(T t) { t.pet(); };
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
• note: the required expression ‘t.pet()’ is invalid, because
P3358R0.C:13:47:
13 | concept has_member_pet = requires(T t) { t.pet(); };
| ~~~~~^~
• error: ‘struct lizard’ has no member named ‘pet’
P3358R0.C:13:44:
13 | concept has_member_pet = requires(T t) { t.pet(); };
| ~~^~~
• note: the operand ‘has_default_pet<T>’ is unsatisfied because
P3358R0.C:19:41:
19 | concept pettable = has_member_pet<T> or has_default_pet<T>;
| ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
• required for the satisfaction of ‘has_default_pet<T>’ [with T = lizard]
P3358R0.C:16:9:
16 | concept has_default_pet = T::is_pettable;
| ^~~~~~~~~~~~~~~
• required for the satisfaction of ‘pettable<auto:1>’ [with auto:1 = lizard]
P3358R0.C:19:9:
19 | concept pettable = has_member_pet<T> or has_default_pet<T>;
| ^~~~~~~~
• error: ‘is_pettable’ is not a member of ‘lizard’
P3358R0.C:16:30:
16 | concept has_default_pet = T::is_pettable;
| ^~~~~~~~~~~
• note: candidate: ‘void pet(dog)’
P3358R0.C:9:6:
9 | void pet(dog);
| ^~~
• note: no known conversion for argument 1 from ‘lizard’ to ‘dog’
P3358R0.C:9:10:
9 | void pet(dog);
| ^~~
• note: candidate: ‘void pet(cat)’
P3358R0.C:10:6:
10 | void pet(cat);
| ^~~
• note: no known conversion for argument 1 from ‘lizard’ to ‘cat’
P3358R0.C:10:10:
10 | void pet(cat);
| ^~~
showing the hierarchical structure of the messages; ideally there
would be a UI here allowing the user to expand/collapse the messages
to drill out into the detail they are interested in.
The structure is also captured in SARIF output (via the "nestingLevel"
property).
gcc/cp/ChangeLog:
PR other/116253
* call.cc (print_conversion_rejection): Remove leading space from
diagnostic messages.
(print_conversion_rejection): Likewise.
(print_arity_information): Likewise.
(print_z_candidate): Likewise. Add auto_diagnostic_nesting_level
before calls to fn_type_unification and diagnose_constraints.
(print_z_candidates): Add auto_diagnostic_nesting_level before
looping over candidates.
(conversion_null_warnings): Remove leading space from
diagnostic messages.
(maybe_inform_about_fndecl_for_bogus_argument_init): Likewise.
* constraint.cc (tsubst_valid_expression_requirement): Add
auto_diagnostic_nesting_level when showing why the expression is
invalid.
(satisfy_disjunction): Likewise when showing operans, and again
when replaying each branch of the disjunction.
(diagnose_constraints): Likewise when replaying satisfaction.
* error.cc (cp_diagnostic_text_starter): Set prefix.
(print_instantiation_full_context): Only show the file
if we're not showing nesting or the user has opted in to
showing location information in nested diagnostics.
(class auto_context_line): New.
(print_instantiation_partial_context_line): Replace calls to
print_location and to diagnostic_show_locus with an
auto_context_line.
(print_instantiation_partial_context): Replace calls to
print_location with an auto_context_line.
(maybe_print_constexpr_context): Likewise.
(print_constrained_decl_info): Likewise.
(print_concept_check_info): Likewise.
(print_constraint_context_head): Likewise.
(print_requires_expression_info): Likewise.
gcc/testsuite/ChangeLog:
PR other/116253
* g++.dg/concepts/nested-diagnostics-1-truncated.C: New test.
* g++.dg/concepts/nested-diagnostics-1.C: New test.
* g++.dg/concepts/nested-diagnostics-2.C: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>