Skip to content

Commit 069942e

Browse files
committed
[Distributed] Improve error message style
1 parent a67824f commit 069942e

8 files changed

+71
-45
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4505,32 +4505,32 @@ ERROR(distributed_actor_isolated_method,none,
45054505
"only 'distributed' instance methods can be called on a potentially remote distributed actor",
45064506
())
45074507
ERROR(distributed_actor_func_param_not_codable,none,
4508-
"distributed instance method parameter '%0' of type %1 does not conform to 'Codable'",
4509-
(StringRef, Type))
4508+
"parameter '%0' of type %1 in %2 does not conform to '%3'",
4509+
(StringRef, Type, DescriptiveDeclKind, StringRef))
45104510
ERROR(distributed_actor_func_result_not_codable,none,
4511-
"%0 result type %0 does not conform to 'Codable'",
4512-
(DescriptiveDeclKind, Type))
4511+
"result type %0 of %1 does not conform to '%2'",
4512+
(Type, DescriptiveDeclKind, StringRef))
45134513
ERROR(distributed_actor_remote_func_implemented_manually,none,
45144514
"distributed instance method's %0 remote counterpart %1 cannot not be implemented manually.",
45154515
(Identifier, Identifier))
45164516
ERROR(nonisolated_distributed_actor_storage,none,
45174517
"'nonisolated' can not be applied to distributed actor stored properties",
45184518
())
45194519
ERROR(distributed_actor_func_nonisolated, none,
4520-
"function %0 cannot be both 'nonisolated' and 'distributed'",
4520+
"cannot declare method %0 as both 'nonisolated' and 'distributed'",
45214521
(DeclName))
45224522
ERROR(distributed_actor_func_private, none,
45234523
"%0 %1 cannot be 'private'",
45244524
(DescriptiveDeclKind, DeclName))
45254525
ERROR(distributed_actor_func_inout, none,
4526-
"%0 %1 cannot declare 'inout' argument %2",
4527-
(DescriptiveDeclKind, DeclName, DeclName))
4526+
"cannot declare 'inout' argument %0 in %1 %2",
4527+
(DeclName, DescriptiveDeclKind, DeclName))
45284528
ERROR(distributed_actor_func_closure, none,
45294529
"%0 %1 cannot declare closure arguments, as they cannot be serialized",
45304530
(DescriptiveDeclKind, DeclName))
45314531
ERROR(distributed_actor_func_variadic, none,
4532-
"%0 %1 cannot declare variadic argument %2",
4533-
(DescriptiveDeclKind, DeclName, DeclName))
4532+
"cannot declare variadic argument %0 in %1 %2",
4533+
(DeclName, DescriptiveDeclKind, DeclName))
45344534
ERROR(distributed_actor_remote_func_is_not_static,none,
45354535
"remote function %0 must be static",
45364536
(DeclName))
@@ -4663,7 +4663,7 @@ ERROR(distributed_actor_func_static,none,
46634663
"'distributed' method cannot be 'static'",
46644664
())
46654665
ERROR(distributed_actor_func_not_in_distributed_actor,none,
4666-
"'distributed' function can only be declared within 'distributed actor'",
4666+
"'distributed' method can only be declared within 'distributed actor'",
46674667
())
46684668
ERROR(distributed_actor_designated_ctor_must_have_one_transport_param,none,
46694669
"designated distributed actor initializer %0 must accept exactly one "

lib/Sema/TypeCheckDistributed.cpp

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,24 @@ void swift::diagnoseDistributedFunctionInNonDistributedActorProtocol(
6969
}
7070
}
7171

72+
73+
/// Add Fix-It text for the given nominal type to adopt Codable.
74+
///
75+
/// Useful when 'Codable' is the 'SerializationRequirement' and a non-Codable
76+
/// function parameter or return value type is detected.
77+
void swift::addCodableFixIt(
78+
const NominalTypeDecl *nominal, InFlightDiagnostic &diag) {
79+
if (nominal->getInherited().empty()) {
80+
SourceLoc fixItLoc = nominal->getBraces().Start;
81+
diag.fixItInsert(fixItLoc, ": Codable");
82+
} else {
83+
ASTContext &ctx = nominal->getASTContext();
84+
SourceLoc fixItLoc = nominal->getInherited().back().getSourceRange().End;
85+
fixItLoc = Lexer::getLocForEndOfToken(ctx.SourceMgr, fixItLoc);
86+
diag.fixItInsert(fixItLoc, ", Codable");
87+
}
88+
}
89+
7290
// ==== ------------------------------------------------------------------------
7391

7492
bool IsDistributedActorRequest::evaluate(
@@ -119,30 +137,32 @@ bool swift::checkDistributedFunction(FuncDecl *func, bool diagnose) {
119137
auto paramTy = func->mapTypeIntoContext(param->getInterfaceType());
120138
if (TypeChecker::conformsToProtocol(paramTy, encodableType, module).isInvalid() ||
121139
TypeChecker::conformsToProtocol(paramTy, decodableType, module).isInvalid()) {
122-
if (diagnose)
123-
func->diagnose(
140+
if (diagnose) {
141+
auto diag = func->diagnose(
124142
diag::distributed_actor_func_param_not_codable,
125-
param->getArgumentName().str(),
126-
param->getInterfaceType()
127-
);
128-
// TODO: suggest a fixit to add Codable to the type?
143+
param->getArgumentName().str(), param->getInterfaceType(),
144+
func->getDescriptiveKind(), "Codable");
145+
if (auto paramNominalTy = paramTy->getAnyNominal()) {
146+
addCodableFixIt(paramNominalTy, diag);
147+
} // else, no nominal type to suggest the fixit for, e.g. a closure
148+
}
129149
return true;
130150
}
131151

132152
if (param->isInOut()) {
133153
param->diagnose(
134154
diag::distributed_actor_func_inout,
135-
func->getDescriptiveKind(), func->getName(),
136-
param->getName()
137-
); // TODO(distributed): offer fixit to remove 'inout'
155+
param->getName(),
156+
func->getDescriptiveKind(), func->getName()
157+
).fixItRemove(param->getSpecifierLoc()); // FIXME(distributed): does not seem to cause the fixit...? Is the Loc invalid...?
138158
return true;
139159
}
140160

141161
if (param->isVariadic()) {
142162
param->diagnose(
143163
diag::distributed_actor_func_variadic,
144-
func->getDescriptiveKind(), func->getName(),
145-
param->getName()
164+
param->getName(),
165+
func->getDescriptiveKind(), func->getName()
146166
);
147167
}
148168
}
@@ -152,13 +172,16 @@ bool swift::checkDistributedFunction(FuncDecl *func, bool diagnose) {
152172
if (!resultType->isVoid()) {
153173
if (TypeChecker::conformsToProtocol(resultType, decodableType, module).isInvalid() ||
154174
TypeChecker::conformsToProtocol(resultType, encodableType, module).isInvalid()) {
155-
if (diagnose)
156-
func->diagnose(
175+
if (diagnose) {
176+
auto diag = func->diagnose(
157177
diag::distributed_actor_func_result_not_codable,
158-
func->getDescriptiveKind(),
159-
func->getResultInterfaceType()
178+
func->getResultInterfaceType(), func->getDescriptiveKind(),
179+
"Codable" // Codable is a typealias, easier to diagnose like that
160180
);
161-
// TODO: suggest a fixit to add Codable to the type?
181+
if (auto resultNominalType = resultType->getAnyNominal()) {
182+
addCodableFixIt(resultNominalType, diag);
183+
}
184+
}
162185
return true;
163186
}
164187
}

lib/Sema/TypeCheckDistributed.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ Type getDistributedActorIdentityType(NominalTypeDecl *actor);
5555
void diagnoseDistributedFunctionInNonDistributedActorProtocol(
5656
const ProtocolDecl *proto, InFlightDiagnostic &diag);
5757

58+
/// Emit a FixIt suggesting to add Codable to the nominal type.
59+
void addCodableFixIt(const NominalTypeDecl *nominal, InFlightDiagnostic &diag);
60+
5861
}
5962

6063

test/Distributed/distributed_actor_inference.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@ distributed enum SomeDistributedActor_3 { } // expected-error{{'distributed' mod
2929

3030
@available(SwiftStdlib 5.6, *)
3131
struct SomeNotActorStruct_2 {
32-
distributed func nopeAsyncThrows() async throws -> Int { 42 } // expected-error{{'distributed' function can only be declared within 'distributed actor'}}
32+
distributed func nopeAsyncThrows() async throws -> Int { 42 } // expected-error{{'distributed' method can only be declared within 'distributed actor'}}
3333
}
3434

3535
@available(SwiftStdlib 5.6, *)
3636
class SomeNotActorClass_3 {
37-
distributed func nopeAsyncThrows() async throws -> Int { 42 } // expected-error{{'distributed' function can only be declared within 'distributed actor'}}
37+
distributed func nopeAsyncThrows() async throws -> Int { 42 } // expected-error{{'distributed' method can only be declared within 'distributed actor'}}
3838
}
3939

4040
@available(SwiftStdlib 5.6, *)
4141
actor SomeNotDistributedActor_4 {
42-
distributed func notInDistActorAsyncThrowing() async throws -> Int { 42 } // expected-error{{'distributed' function can only be declared within 'distributed actor'}}
42+
distributed func notInDistActorAsyncThrowing() async throws -> Int { 42 } // expected-error{{'distributed' method can only be declared within 'distributed actor'}}
4343
}
4444

4545
protocol DP {
46-
distributed func hello() // expected-error{{'distributed' function can only be declared within 'distributed actor'}}
46+
distributed func hello() // expected-error{{'distributed' method can only be declared within 'distributed actor'}}
4747
}
4848

4949
@available(SwiftStdlib 5.6, *)
@@ -58,7 +58,7 @@ protocol DPOK2: DPOK {
5858

5959
@available(SwiftStdlib 5.6, *)
6060
enum SomeNotActorEnum_5 {
61-
distributed func nopeAsyncThrows() async throws -> Int { 42 } // expected-error{{'distributed' function can only be declared within 'distributed actor'}}
61+
distributed func nopeAsyncThrows() async throws -> Int { 42 } // expected-error{{'distributed' method can only be declared within 'distributed actor'}}
6262
}
6363

6464
@available(SwiftStdlib 5.6, *)

test/Distributed/distributed_actor_is_experimental_enabled_missing_import.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ distributed actor class DAC {}
1515

1616
actor A {
1717
func normal() async {}
18-
distributed func dist() {} // expected-error{{'distributed' function can only be declared within 'distributed actor'}}
19-
distributed func distAsync() async {} // expected-error{{'distributed' function can only be declared within 'distributed actor'}}
18+
distributed func dist() {} // expected-error{{'distributed' method can only be declared within 'distributed actor'}}
19+
distributed func distAsync() async {} // expected-error{{'distributed' method can only be declared within 'distributed actor'}}
2020

2121
distributed var neverOk: String { // expected-error{{'distributed' modifier cannot be applied to this declaration}}
2222
"vars are not allowed to be distributed *ever* anyway"

test/Distributed/distributed_actor_isolation.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ actor LocalActor_1 {
2222
var mutable: String = ""
2323

2424
distributed func nope() {
25-
// expected-error@-1{{'distributed' function can only be declared within 'distributed actor'}}
25+
// expected-error@-1{{'distributed' method can only be declared within 'distributed actor'}}
2626
}
2727
}
2828

@@ -68,23 +68,23 @@ distributed actor DistributedActor_1 {
6868
distributed func distIntString(int: Int, two: String) async throws -> (String) { "\(int) + \(two)" } // ok
6969

7070
distributed func dist(notCodable: NotCodableValue) async throws {
71-
// expected-error@-1 {{distributed instance method parameter 'notCodable' of type 'NotCodableValue' does not conform to 'Codable'}}
71+
// expected-error@-1 {{parameter 'notCodable' of type 'NotCodableValue' in distributed instance method does not conform to 'Codable'}}
7272
}
7373
distributed func distBadReturn(int: Int) async throws -> NotCodableValue {
74-
// expected-error@-1 {{distributed instance method result type 'NotCodableValue' does not conform to 'Codable'}}
74+
// expected-error@-1 {{result type 'NotCodableValue' of distributed instance method does not conform to 'Codable'}}
7575
fatalError()
7676
}
7777

7878
distributed func varargs(int: Int...) {
79-
// expected-error@-1{{distributed instance method 'varargs(int:)' cannot declare variadic argument 'int'}}
79+
// expected-error@-1{{cannot declare variadic argument 'int' in distributed instance method 'varargs(int:)'}}
8080
}
8181

8282
distributed func closure(close: () -> String) {
83-
// expected-error@-1{{distributed instance method parameter 'close' of type '() -> String' does not conform to 'Codable'}}
83+
// expected-error@-1{{parameter 'close' of type '() -> String' in distributed instance method does not conform to 'Codable'}}
8484
}
8585

8686
distributed func noInout(inNOut burger: inout String) {
87-
// expected-error@-1{{distributed instance method 'noInout(inNOut:)' cannot declare 'inout' argument 'burger'}}
87+
// expected-error@-1{{cannot declare 'inout' argument 'burger' in distributed instance method 'noInout(inNOut:)'}}
8888
}
8989

9090
distributed func distReturnGeneric<T: Codable & Sendable>(item: T) async throws -> T { // ok
@@ -94,7 +94,7 @@ distributed actor DistributedActor_1 {
9494
fatalError()
9595
}
9696
distributed func distBadReturnGeneric<T: Sendable>(int: Int) async throws -> T {
97-
// expected-error@-1 {{distributed instance method result type 'T' does not conform to 'Codable'}}
97+
// expected-error@-1 {{result type 'T' of distributed instance method does not conform to 'Codable'}}
9898
fatalError()
9999
}
100100

@@ -105,7 +105,7 @@ distributed actor DistributedActor_1 {
105105
value
106106
}
107107
distributed func distBadGenericParam<T: Sendable>(int: T) async throws {
108-
// expected-error@-1 {{distributed instance method parameter 'int' of type 'T' does not conform to 'Codable'}}
108+
// expected-error@-1 {{parameter 'int' of type 'T' in distributed instance method does not conform to 'Codable'}}
109109
fatalError()
110110
}
111111

test/Distributed/distributed_actor_nonisolated.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ distributed actor DA {
3838
}
3939

4040
nonisolated distributed func nonisolatedDistributed() async {
41-
// expected-error@-1{{function 'nonisolatedDistributed()' cannot be both 'nonisolated' and 'distributed'}}{{3-15=}}
41+
// expected-error@-1{{cannot declare method 'nonisolatedDistributed()' as both 'nonisolated' and 'distributed'}}{{3-15=}}
4242
fatalError()
4343
}
4444

4545
distributed nonisolated func distributedNonisolated() async {
46-
// expected-error@-1{{function 'distributedNonisolated()' cannot be both 'nonisolated' and 'distributed'}}{{15-27=}}
46+
// expected-error@-1{{cannot declare method 'distributedNonisolated()' as both 'nonisolated' and 'distributed'}}{{15-27=}}
4747
fatalError()
4848
}
4949

test/Distributed/distributed_protocol_isolation.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ typealias DefaultActorTransport = AnyActorTransport
1111
// MARK: Distributed actor protocols
1212

1313
protocol WrongDistFuncs {
14-
distributed func notDistActor() // expected-error{{'distributed' function can only be declared within 'distributed actor'}}{{5-17=}} {{25-25=: DistributedActor}}
14+
distributed func notDistActor() // expected-error{{'distributed' method can only be declared within 'distributed actor'}}{{5-17=}} {{25-25=: DistributedActor}}
1515
}
1616

1717
protocol DistProtocol: DistributedActor {
@@ -199,7 +199,7 @@ extension DistributedTacoMaker {
199199

200200
extension TacoPreparation {
201201
distributed func makeSalsa() -> Salsa {}
202-
// expected-error@-1{{'distributed' function can only be declared within 'distributed actor'}}
202+
// expected-error@-1{{'distributed' method can only be declared within 'distributed actor'}}
203203
}
204204

205205
distributed actor TacoWorker: DistributedTacoMaker {} // implemented in extensions

0 commit comments

Comments
 (0)