Skip to content

Commit 831d517

Browse files
committed
Clean up format_provider uses
1 parent 1131c45 commit 831d517

File tree

8 files changed

+39
-76
lines changed

8 files changed

+39
-76
lines changed

toolchain/check/context.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "toolchain/check/inst_block_stack.h"
2222
#include "toolchain/check/merge.h"
2323
#include "toolchain/diagnostics/diagnostic_emitter.h"
24+
#include "toolchain/diagnostics/format_providers.h"
2425
#include "toolchain/lex/tokenized_buffer.h"
2526
#include "toolchain/parse/node_ids.h"
2627
#include "toolchain/parse/node_kind.h"
@@ -362,13 +363,6 @@ static auto DiagnoseInvalidQualifiedNameAccess(Context& context, SemIRLoc loc,
362363
// TODO: Support scoped entities other than just classes.
363364
auto class_info = context.classes().Get(class_type->class_id);
364365

365-
CARBON_DIAGNOSTIC(ClassInvalidMemberAccess, Error,
366-
"cannot access {0} member `{1}` of type {2}",
367-
SemIR::AccessKind, SemIR::NameId, SemIR::TypeId);
368-
CARBON_DIAGNOSTIC(ClassMemberDefinition, Note,
369-
"the {0} member `{1}` is defined here", SemIR::AccessKind,
370-
SemIR::NameId);
371-
372366
auto parent_type_id = class_info.self_type_id;
373367

374368
if (access_kind == SemIR::AccessKind::Private && is_parent_access) {
@@ -384,10 +378,15 @@ static auto DiagnoseInvalidQualifiedNameAccess(Context& context, SemIRLoc loc,
384378
}
385379
}
386380

381+
CARBON_DIAGNOSTIC(
382+
ClassInvalidMemberAccess, Error,
383+
"cannot access {0:private|protected} member `{1}` of type {2}",
384+
BoolAsSelect, SemIR::NameId, SemIR::TypeId);
385+
CARBON_DIAGNOSTIC(ClassMemberDeclaration, Note, "declared here");
387386
context.emitter()
388-
.Build(loc, ClassInvalidMemberAccess, access_kind, name_id,
389-
parent_type_id)
390-
.Note(scope_result_id, ClassMemberDefinition, access_kind, name_id)
387+
.Build(loc, ClassInvalidMemberAccess,
388+
access_kind == SemIR::AccessKind::Private, name_id, parent_type_id)
389+
.Note(scope_result_id, ClassMemberDeclaration)
391390
.Emit();
392391
}
393392

toolchain/check/testdata/class/access_modifers.carbon

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,23 @@ fn Run() {
3030
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE+7]]:21: error: cannot access private member `radius` of type `Circle`
3131
// CHECK:STDERR: let radius: i32 = circle.radius;
3232
// CHECK:STDERR: ^~~~~~~~~~~~~
33-
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE-17]]:15: note: the private member `radius` is defined here
33+
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE-17]]:15: note: declared here
3434
// CHECK:STDERR: private var radius: i32;
3535
// CHECK:STDERR: ^~~~~~~~~~~
3636
// CHECK:STDERR:
3737
let radius: i32 = circle.radius;
3838
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE+7]]:3: error: cannot access private member `radius` of type `Circle`
3939
// CHECK:STDERR: circle.radius = 5;
4040
// CHECK:STDERR: ^~~~~~~~~~~~~
41-
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE-25]]:15: note: the private member `radius` is defined here
41+
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE-25]]:15: note: declared here
4242
// CHECK:STDERR: private var radius: i32;
4343
// CHECK:STDERR: ^~~~~~~~~~~
4444
// CHECK:STDERR:
4545
circle.radius = 5;
4646
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE+7]]:3: error: cannot access private member `SOME_INTERNAL_CONSTANT` of type `Circle`
4747
// CHECK:STDERR: circle.SOME_INTERNAL_CONSTANT;
4848
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49-
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE-32]]:15: note: the private member `SOME_INTERNAL_CONSTANT` is defined here
49+
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE-32]]:15: note: declared here
5050
// CHECK:STDERR: private let SOME_INTERNAL_CONSTANT: i32 = 5;
5151
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~
5252
// CHECK:STDERR:
@@ -55,7 +55,7 @@ fn Run() {
5555
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE+7]]:3: error: cannot access private member `SomeInternalFunction` of type `Circle`
5656
// CHECK:STDERR: circle.SomeInternalFunction();
5757
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
58-
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE-39]]:3: note: the private member `SomeInternalFunction` is defined here
58+
// CHECK:STDERR: fail_private_field_access.carbon:[[@LINE-39]]:3: note: declared here
5959
// CHECK:STDERR: private fn SomeInternalFunction() -> i32 {
6060
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6161
// CHECK:STDERR:
@@ -74,7 +74,7 @@ fn Run() {
7474
// CHECK:STDERR: fail_protected_field_access.carbon:[[@LINE+7]]:16: error: cannot access protected member `x` of type `A`
7575
// CHECK:STDERR: let x: i32 = A.x;
7676
// CHECK:STDERR: ^~~
77-
// CHECK:STDERR: fail_protected_field_access.carbon:[[@LINE-7]]:17: note: the protected member `x` is defined here
77+
// CHECK:STDERR: fail_protected_field_access.carbon:[[@LINE-7]]:17: note: declared here
7878
// CHECK:STDERR: protected var x: i32;
7979
// CHECK:STDERR: ^~~~~~
8080
// CHECK:STDERR:
@@ -123,15 +123,15 @@ class A {
123123
// CHECK:STDERR: fail_global_access.carbon:[[@LINE+7]]:14: error: cannot access protected member `x` of type `A`
124124
// CHECK:STDERR: let x: i32 = A.x;
125125
// CHECK:STDERR: ^~~
126-
// CHECK:STDERR: fail_global_access.carbon:[[@LINE-7]]:17: note: the protected member `x` is defined here
126+
// CHECK:STDERR: fail_global_access.carbon:[[@LINE-7]]:17: note: declared here
127127
// CHECK:STDERR: protected let x: i32 = 5;
128128
// CHECK:STDERR: ^
129129
// CHECK:STDERR:
130130
let x: i32 = A.x;
131131
// CHECK:STDERR: fail_global_access.carbon:[[@LINE+6]]:14: error: cannot access private member `y` of type `A`
132132
// CHECK:STDERR: let y: i32 = A.y;
133133
// CHECK:STDERR: ^~~
134-
// CHECK:STDERR: fail_global_access.carbon:[[@LINE-14]]:15: note: the private member `y` is defined here
134+
// CHECK:STDERR: fail_global_access.carbon:[[@LINE-14]]:15: note: declared here
135135
// CHECK:STDERR: private let y: i32 = 5;
136136
// CHECK:STDERR: ^
137137
let y: i32 = A.y;

toolchain/check/testdata/class/inheritance_access.carbon

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class Square {
8282
// CHECK:STDERR: fail_inherited_private_field_access.carbon:[[@LINE+7]]:12: error: cannot access private member `y` of type `Shape`
8383
// CHECK:STDERR: return self.y;
8484
// CHECK:STDERR: ^~~~~~
85-
// CHECK:STDERR: fail_inherited_private_field_access.carbon:[[@LINE-10]]:15: note: the private member `y` is defined here
85+
// CHECK:STDERR: fail_inherited_private_field_access.carbon:[[@LINE-10]]:15: note: declared here
8686
// CHECK:STDERR: private var y: i32;
8787
// CHECK:STDERR: ^~~~~~
8888
// CHECK:STDERR:
@@ -121,7 +121,7 @@ class C {
121121
// CHECK:STDERR: fail_noninstance_private_on_parent.carbon:[[@LINE+7]]:12: error: cannot access private member `F` of type `B`
122122
// CHECK:STDERR: fn G() { Self.F(); }
123123
// CHECK:STDERR: ^~~~~~
124-
// CHECK:STDERR: fail_noninstance_private_on_parent.carbon:[[@LINE-8]]:3: note: the private member `F` is defined here
124+
// CHECK:STDERR: fail_noninstance_private_on_parent.carbon:[[@LINE-8]]:3: note: declared here
125125
// CHECK:STDERR: private fn F() {}
126126
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
127127
// CHECK:STDERR:
@@ -161,7 +161,7 @@ class B {
161161
// CHECK:STDERR: fail_non_inherited_access.carbon:[[@LINE+7]]:5: error: cannot access private member `SOME_PRIVATE_CONSTANT` of type `A`
162162
// CHECK:STDERR: A.SOME_PRIVATE_CONSTANT;
163163
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~
164-
// CHECK:STDERR: fail_non_inherited_access.carbon:[[@LINE-14]]:15: note: the private member `SOME_PRIVATE_CONSTANT` is defined here
164+
// CHECK:STDERR: fail_non_inherited_access.carbon:[[@LINE-14]]:15: note: declared here
165165
// CHECK:STDERR: private let SOME_PRIVATE_CONSTANT: i32 = 5;
166166
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~
167167
// CHECK:STDERR:
@@ -170,7 +170,7 @@ class B {
170170
// CHECK:STDERR: fail_non_inherited_access.carbon:[[@LINE+7]]:12: error: cannot access protected member `SOME_PROTECTED_CONSTANT` of type `A`
171171
// CHECK:STDERR: return A.SOME_PROTECTED_CONSTANT;
172172
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
173-
// CHECK:STDERR: fail_non_inherited_access.carbon:[[@LINE-24]]:17: note: the protected member `SOME_PROTECTED_CONSTANT` is defined here
173+
// CHECK:STDERR: fail_non_inherited_access.carbon:[[@LINE-24]]:17: note: declared here
174174
// CHECK:STDERR: protected let SOME_PROTECTED_CONSTANT: i32 = 5;
175175
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~
176176
// CHECK:STDERR:
@@ -181,7 +181,7 @@ class B {
181181
// CHECK:STDERR: fail_non_inherited_access.carbon:[[@LINE+7]]:12: error: cannot access protected member `INTERNAL_CONSTANT` of type `Internal`
182182
// CHECK:STDERR: return self.internal.INTERNAL_CONSTANT;
183183
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
184-
// CHECK:STDERR: fail_non_inherited_access.carbon:[[@LINE-30]]:17: note: the protected member `INTERNAL_CONSTANT` is defined here
184+
// CHECK:STDERR: fail_non_inherited_access.carbon:[[@LINE-30]]:17: note: declared here
185185
// CHECK:STDERR: protected let INTERNAL_CONSTANT: i32 = 5;
186186
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~
187187
// CHECK:STDERR:
@@ -203,7 +203,7 @@ class B {
203203
// CHECK:STDERR: fail_compound_member_access.carbon:[[@LINE+6]]:11: error: cannot access private member `x` of type `A`
204204
// CHECK:STDERR: self.(A.x);
205205
// CHECK:STDERR: ^~~
206-
// CHECK:STDERR: fail_compound_member_access.carbon:[[@LINE-9]]:15: note: the private member `x` is defined here
206+
// CHECK:STDERR: fail_compound_member_access.carbon:[[@LINE-9]]:15: note: declared here
207207
// CHECK:STDERR: private var x: i32;
208208
// CHECK:STDERR: ^~~~~~
209209
self.(A.x);

toolchain/diagnostics/diagnostic_kind.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ CARBON_DIAGNOSTIC_KIND(ExternLibraryOnDefinition)
367367
CARBON_DIAGNOSTIC_KIND(ExternLibraryIsCurrentLibrary)
368368

369369
// Access modifiers.
370-
CARBON_DIAGNOSTIC_KIND(ClassMemberDefinition)
370+
CARBON_DIAGNOSTIC_KIND(ClassMemberDeclaration)
371371
CARBON_DIAGNOSTIC_KIND(ClassInvalidMemberAccess)
372372

373373
// Alias diagnostics.

toolchain/docs/diagnostics.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,14 @@ methods for formatting arguments:
171171
allocations are required.
172172
- `llvm::StringRef` is disallowed due to lifetime issues.
173173
- `llvm::format_provider<...>` specializations.
174-
- This can be used when formatting the parameter doesn't require
175-
additional context.
176-
- For example, `Lex::TokenKind` and `Parse::RelativeLoc` provide
177-
diagnostic formatting this way.
174+
- `BoolAsSelect` and `IntAsSelect` from
175+
[format_providers.h](/toolchain/diagnostics/format_providers.h) are
176+
recommended for many cases, because they allow putting the output string
177+
in the format.
178+
- `IntAsSelect` can also be used to support pluralization.
179+
- Custom providers can also be added for non-translated values. For
180+
example, `Lex::TokenKind` refers to syntax elements, and so can safely
181+
have its own format provider.
178182
- `DiagnosticConverter::ConvertArg` overrides.
179183
- This can provide additional context to a formatter.
180184
- For example, formatting `SemIR::NameId` accesses the IR's name list.

toolchain/lex/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ cc_library(
7474
":helpers",
7575
"//common:check",
7676
"//toolchain/diagnostics:diagnostic_emitter",
77+
"//toolchain/diagnostics:format_providers",
7778
"@llvm-project//llvm:Support",
7879
],
7980
)

toolchain/lex/numeric_literal.cpp

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,10 @@
99
#include "common/check.h"
1010
#include "llvm/ADT/StringExtras.h"
1111
#include "llvm/Support/FormatVariadicDetails.h"
12+
#include "toolchain/diagnostics/format_providers.h"
1213
#include "toolchain/lex/character_set.h"
1314
#include "toolchain/lex/helpers.h"
1415

15-
// We use formatv primarily for diagnostics. In these cases, it's expected that
16-
// the spelling in source code should be used.
17-
template <>
18-
struct llvm::format_provider<Carbon::Lex::NumericLiteral::Radix> {
19-
using Radix = Carbon::Lex::NumericLiteral::Radix;
20-
static void format(const Radix& radix, raw_ostream& out,
21-
StringRef /*style*/) {
22-
switch (radix) {
23-
case Radix::Binary:
24-
out << "binary";
25-
break;
26-
case Radix::Decimal:
27-
out << "decimal";
28-
break;
29-
case Radix::Hexadecimal:
30-
out << "hexadecimal";
31-
break;
32-
}
33-
}
34-
};
35-
3616
namespace Carbon::Lex {
3717

3818
auto NumericLiteral::Lex(llvm::StringRef source_text)
@@ -308,10 +288,12 @@ auto NumericLiteral::Parser::CheckDigitSequence(llvm::StringRef text,
308288
continue;
309289
}
310290

311-
CARBON_DIAGNOSTIC(InvalidDigit, Error,
312-
"invalid digit '{0}' in {1} numeric literal", char,
313-
NumericLiteral::Radix);
314-
emitter_.Emit(text.begin() + i, InvalidDigit, c, radix);
291+
CARBON_DIAGNOSTIC(
292+
InvalidDigit, Error,
293+
"invalid digit '{0}' in {1:=2:binary|=10:decimal|=16:hexadecimal} "
294+
"numeric literal",
295+
char, IntAsSelect);
296+
emitter_.Emit(text.begin() + i, InvalidDigit, c, static_cast<int>(radix));
315297
return {.ok = false};
316298
}
317299

toolchain/sem_ir/name_scope.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,6 @@ enum class AccessKind : int8_t {
1818
Private,
1919
};
2020

21-
} // namespace Carbon::SemIR
22-
23-
template <>
24-
struct llvm::format_provider<Carbon::SemIR::AccessKind> {
25-
using AccessKind = Carbon::SemIR::AccessKind;
26-
static void format(const AccessKind& loc, raw_ostream& out,
27-
StringRef /*style*/) {
28-
switch (loc) {
29-
case AccessKind::Private:
30-
out << "private";
31-
break;
32-
case AccessKind::Protected:
33-
out << "protected";
34-
break;
35-
case AccessKind::Public:
36-
out << "public";
37-
break;
38-
}
39-
}
40-
};
41-
42-
namespace Carbon::SemIR {
43-
4421
struct NameScope : Printable<NameScope> {
4522
struct Entry {
4623
NameId name_id;

0 commit comments

Comments
 (0)