99#include " toolchain/check/convert.h"
1010#include " toolchain/check/deduce.h"
1111#include " toolchain/check/function.h"
12+ #include " toolchain/diagnostics/format_providers.h"
1213#include " toolchain/sem_ir/builtin_function_kind.h"
1314#include " toolchain/sem_ir/builtin_inst_kind.h"
1415#include " toolchain/sem_ir/entity_with_params_base.h"
1819
1920namespace Carbon ::Check {
2021
22+ namespace {
23+ // Entity kinds for the diagnostic. Converted to an int for a select.
24+ enum class EntityKind : uint8_t {
25+ Function,
26+ GenericClass,
27+ GenericInterface,
28+ };
29+ } // namespace
30+
2131// Resolves the callee expression in a call to a specific callee, or diagnoses
2232// if no specific callee can be identified. This verifies the arity of the
2333// callee and determines any compile-time arguments, but doesn't check that the
@@ -30,7 +40,7 @@ namespace Carbon::Check {
3040// callee is not generic, or `nullopt` if an error has been diagnosed.
3141static auto ResolveCalleeInCall (Context& context, SemIR::LocId loc_id,
3242 const SemIR::EntityWithParamsBase& entity,
33- llvm::StringLiteral entity_kind_for_diagnostic,
43+ EntityKind entity_kind_for_diagnostic,
3444 SemIR::GenericId entity_generic_id,
3545 SemIR::SpecificId enclosing_specific_id,
3646 SemIR::InstId self_id,
@@ -42,16 +52,20 @@ static auto ResolveCalleeInCall(Context& context, SemIR::LocId loc_id,
4252 auto params = context.inst_blocks ().GetOrEmpty (callee_info.param_refs_id );
4353 if (arg_ids.size () != params.size ()) {
4454 CARBON_DIAGNOSTIC (CallArgCountMismatch, Error,
45- " {0} argument(s) passed to {1} expecting "
46- " {2} argument(s)." ,
47- int , llvm::StringLiteral, int );
48- CARBON_DIAGNOSTIC (InCallToEntity, Note, " calling {0} declared here" ,
49- llvm::StringLiteral);
55+ " {0} argument(s) passed to "
56+ " {1:=0:function|=1:generic class|=2:generic interface}"
57+ " expecting {2} argument(s)." ,
58+ int , IntAsSelect, int );
59+ CARBON_DIAGNOSTIC (
60+ InCallToEntity, Note,
61+ " calling {0:=0:function|=1:generic class|=2:generic interface}"
62+ " declared here" ,
63+ IntAsSelect);
5064 context.emitter ()
5165 .Build (loc_id, CallArgCountMismatch, arg_ids.size (),
52- entity_kind_for_diagnostic, params.size ())
66+ static_cast < int >( entity_kind_for_diagnostic) , params.size ())
5367 .Note (callee_info.callee_loc , InCallToEntity,
54- entity_kind_for_diagnostic)
68+ static_cast < int >( entity_kind_for_diagnostic) )
5569 .Emit ();
5670 return std::nullopt ;
5771 }
@@ -79,8 +93,9 @@ static auto PerformCallToGenericClass(Context& context, SemIR::LocId loc_id,
7993 -> SemIR::InstId {
8094 const auto & generic_class = context.classes ().Get (class_id);
8195 auto callee_specific_id = ResolveCalleeInCall (
82- context, loc_id, generic_class, " generic class" , generic_class.generic_id ,
83- enclosing_specific_id, /* self_id=*/ SemIR::InstId::Invalid, arg_ids);
96+ context, loc_id, generic_class, EntityKind::GenericClass,
97+ generic_class.generic_id , enclosing_specific_id,
98+ /* self_id=*/ SemIR::InstId::Invalid, arg_ids);
8499 if (!callee_specific_id) {
85100 return SemIR::InstId::BuiltinError;
86101 }
@@ -98,8 +113,9 @@ static auto PerformCallToGenericInterface(
98113 llvm::ArrayRef<SemIR::InstId> arg_ids) -> SemIR::InstId {
99114 const auto & interface = context.interfaces ().Get (interface_id);
100115 auto callee_specific_id = ResolveCalleeInCall (
101- context, loc_id, interface, " generic interface" , interface.generic_id ,
102- enclosing_specific_id, /* self_id=*/ SemIR::InstId::Invalid, arg_ids);
116+ context, loc_id, interface, EntityKind::GenericInterface,
117+ interface.generic_id , enclosing_specific_id,
118+ /* self_id=*/ SemIR::InstId::Invalid, arg_ids);
103119 if (!callee_specific_id) {
104120 return SemIR::InstId::BuiltinError;
105121 }
@@ -142,7 +158,7 @@ auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id,
142158 // If the callee is a generic function, determine the generic argument values
143159 // for the call.
144160 auto callee_specific_id = ResolveCalleeInCall (
145- context, loc_id, callable, " function " , callable.generic_id ,
161+ context, loc_id, callable, EntityKind::Function , callable.generic_id ,
146162 callee_function.enclosing_specific_id , callee_function.self_id , arg_ids);
147163 if (!callee_specific_id) {
148164 return SemIR::InstId::BuiltinError;
0 commit comments