66
77#include " toolchain/base/kind_switch.h"
88#include " toolchain/check/import_ref.h"
9+ #include " toolchain/diagnostics/format_providers.h"
910#include " toolchain/sem_ir/ids.h"
1011#include " toolchain/sem_ir/typed_insts.h"
1112
1213namespace Carbon ::Check {
1314
15+ // Explicit or implicit parameters. Used in diagnostics.
16+ enum class ParamKind : uint8_t {
17+ Explicit,
18+ Implicit,
19+ };
20+
21+ } // namespace Carbon::Check
22+
23+ // `ParamKind` is formatted in diagnostics as `{0}parameters`, and we only add
24+ // text for implicit paramseters.
25+ template <>
26+ struct llvm ::format_provider<Carbon::Check::ParamKind> {
27+ using ParamKind = Carbon::Check::ParamKind;
28+ static void format (const ParamKind& kind, raw_ostream& out,
29+ StringRef /* style*/ ) {
30+ if (kind == ParamKind::Implicit) {
31+ out << " implicit " ;
32+ }
33+ }
34+ };
35+
36+ namespace Carbon ::Check {
37+
1438CARBON_DIAGNOSTIC (RedeclPrevDecl, Note, " previously declared here" );
1539
1640// Diagnoses a redeclaration which is redundant.
@@ -193,10 +217,12 @@ static auto EntityHasParamError(Context& context, const DeclParams& info)
193217
194218// Returns false if a param differs for a redeclaration. The caller is expected
195219// to provide a diagnostic.
196- static auto CheckRedeclParam (
197- Context& context, llvm::StringLiteral param_diag_label, int32_t param_index,
198- SemIR::InstId new_param_pattern_id, SemIR::InstId prev_param_pattern_id,
199- SemIR::SpecificId prev_specific_id, bool diagnose) -> bool {
220+ static auto CheckRedeclParam (Context& context, ParamKind param_kind,
221+ int32_t param_index,
222+ SemIR::InstId new_param_pattern_id,
223+ SemIR::InstId prev_param_pattern_id,
224+ SemIR::SpecificId prev_specific_id, bool diagnose)
225+ -> bool {
200226 // TODO: Consider differentiating between type and name mistakes. For now,
201227 // taking the simpler approach because I also think we may want to refactor
202228 // params.
@@ -205,15 +231,15 @@ static auto CheckRedeclParam(
205231 return ;
206232 }
207233 CARBON_DIAGNOSTIC (RedeclParamDiffers, Error,
208- " redeclaration differs at {0}parameter {1}" ,
209- llvm::StringLiteral, int32_t );
234+ " redeclaration differs at {0}parameter {1}" , ParamKind,
235+ int32_t );
210236 CARBON_DIAGNOSTIC (RedeclParamPrevious, Note,
211237 " previous declaration's corresponding {0}parameter here" ,
212- llvm::StringLiteral );
238+ ParamKind );
213239 context.emitter ()
214- .Build (new_param_pattern_id, RedeclParamDiffers, param_diag_label ,
240+ .Build (new_param_pattern_id, RedeclParamDiffers, param_kind ,
215241 param_index + 1 )
216- .Note (prev_param_pattern_id, RedeclParamPrevious, param_diag_label )
242+ .Note (prev_param_pattern_id, RedeclParamPrevious, param_kind )
217243 .Emit ();
218244 };
219245
@@ -265,7 +291,7 @@ static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc,
265291 SemIR::InstBlockId new_param_patterns_id,
266292 SemIRLoc prev_decl_loc,
267293 SemIR::InstBlockId prev_param_patterns_id,
268- llvm::StringLiteral param_diag_label ,
294+ ParamKind param_kind ,
269295 SemIR::SpecificId prev_specific_id, bool diagnose)
270296 -> bool {
271297 // This will often occur for empty params.
@@ -278,19 +304,18 @@ static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc,
278304 if (!diagnose) {
279305 return false ;
280306 }
281- CARBON_DIAGNOSTIC (RedeclParamListDiffers, Error,
282- " redeclaration differs because of {1}{0}parameter list" ,
283- llvm::StringLiteral, llvm::StringLiteral);
307+ CARBON_DIAGNOSTIC (
308+ RedeclParamListDiffers, Error,
309+ " redeclaration differs because of {1:'|missing '}{0}parameter list" ,
310+ ParamKind, FormatBool);
284311 CARBON_DIAGNOSTIC (RedeclParamListPrevious, Note,
285- " previously declared with{1 } {0}parameter list" ,
286- llvm::StringLiteral, llvm::StringLiteral );
312+ " previously declared {1:with|without } {0}parameter list" ,
313+ ParamKind, FormatBool );
287314 context.emitter ()
288- .Build (new_decl_loc, RedeclParamListDiffers, param_diag_label,
289- new_param_patterns_id.is_valid () ? llvm::StringLiteral (" " )
290- : " missing " )
291- .Note (
292- prev_decl_loc, RedeclParamListPrevious, param_diag_label,
293- prev_param_patterns_id.is_valid () ? llvm::StringLiteral (" " ) : " out" )
315+ .Build (new_decl_loc, RedeclParamListDiffers, param_kind,
316+ {.value = new_param_patterns_id.is_valid ()})
317+ .Note (prev_decl_loc, RedeclParamListPrevious, param_kind,
318+ {.value = prev_param_patterns_id.is_valid ()})
294319 .Emit ();
295320 return false ;
296321 }
@@ -307,24 +332,23 @@ static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc,
307332 }
308333 CARBON_DIAGNOSTIC (
309334 RedeclParamCountDiffers, Error,
310- " redeclaration differs because of {0}parameter count of {1}" ,
311- llvm::StringLiteral, int32_t );
335+ " redeclaration differs because of {0}parameter count of {1}" , ParamKind,
336+ int32_t );
312337 CARBON_DIAGNOSTIC (RedeclParamCountPrevious, Note,
313338 " previously declared with {0}parameter count of {1}" ,
314- llvm::StringLiteral , int32_t );
339+ ParamKind , int32_t );
315340 context.emitter ()
316- .Build (new_decl_loc, RedeclParamCountDiffers, param_diag_label ,
341+ .Build (new_decl_loc, RedeclParamCountDiffers, param_kind ,
317342 new_param_pattern_ids.size ())
318- .Note (prev_decl_loc, RedeclParamCountPrevious, param_diag_label ,
343+ .Note (prev_decl_loc, RedeclParamCountPrevious, param_kind ,
319344 prev_param_pattern_ids.size ())
320345 .Emit ();
321346 return false ;
322347 }
323348 for (auto [index, new_param_pattern_id, prev_param_pattern_id] :
324349 llvm::enumerate (new_param_pattern_ids, prev_param_pattern_ids)) {
325- if (!CheckRedeclParam (context, param_diag_label, index,
326- new_param_pattern_id, prev_param_pattern_id,
327- prev_specific_id, diagnose)) {
350+ if (!CheckRedeclParam (context, param_kind, index, new_param_pattern_id,
351+ prev_param_pattern_id, prev_specific_id, diagnose)) {
328352 return false ;
329353 }
330354 }
@@ -412,13 +436,13 @@ auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity,
412436 }
413437 if (!CheckRedeclParams (context, new_entity.loc ,
414438 new_entity.implicit_param_patterns_id , prev_entity.loc ,
415- prev_entity.implicit_param_patterns_id , " implicit " ,
416- prev_specific_id, diagnose)) {
439+ prev_entity.implicit_param_patterns_id ,
440+ ParamKind::Implicit, prev_specific_id, diagnose)) {
417441 return false ;
418442 }
419443 if (!CheckRedeclParams (context, new_entity.loc , new_entity.param_patterns_id ,
420- prev_entity.loc , prev_entity.param_patterns_id , " " ,
421- prev_specific_id, diagnose)) {
444+ prev_entity.loc , prev_entity.param_patterns_id ,
445+ ParamKind::Explicit, prev_specific_id, diagnose)) {
422446 return false ;
423447 }
424448 if (check_syntax &&
0 commit comments