Skip to content

Commit d48393b

Browse files
authored
Merge pull request swiftlang#35108 from etcwilde/ewilde/fixit-actor-protocol-conformance
[Concurrency] Emit fixit to add actorIndependent attribute
2 parents beb6caf + 1d53d74 commit d48393b

File tree

4 files changed

+31
-17
lines changed

4 files changed

+31
-17
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4132,6 +4132,9 @@ NOTE(note_add_async_to_function,none,
41324132
"add 'async' to function %0 to make it asynchronous", (DeclName))
41334133
NOTE(note_add_asynchandler_to_function,none,
41344134
"add '@asyncHandler' to function %0 to create an implicit asynchronous context", (DeclName))
4135+
NOTE(note_add_actorindependent_to_decl,none,
4136+
"add '@actorIndependent' to %0 to make this %1 independent of the actor",
4137+
(DeclName, DescriptiveDeclKind))
41354138
NOTE(note_add_globalactor_to_function,none,
41364139
"add '@%0' to make %1 %2 part of global actor %3",
41374140
(StringRef, DescriptiveDeclKind, DeclName, Type))
@@ -4255,10 +4258,6 @@ WARNING(shared_mutable_state_access,none,
42554258
ERROR(actor_isolated_witness,none,
42564259
"actor-isolated %0 %1 cannot be used to satisfy a protocol requirement",
42574260
(DescriptiveDeclKind, DeclName))
4258-
ERROR(actor_isolated_witness_could_be_async_handler,none,
4259-
"actor-isolated %0 %1 cannot be used to satisfy a protocol requirement; "
4260-
"did you mean to make it an asychronous handler?",
4261-
(DescriptiveDeclKind, DeclName))
42624261
ERROR(global_actor_isolated_requirement,none,
42634262
"%0 %1 must be isolated to the global actor %2 to satisfy corresponding "
42644263
"requirement from protocol %3",

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,20 +2654,29 @@ bool ConformanceChecker::checkActorIsolation(
26542654
ActorIsolationRestriction::forDeclaration(witness)) {
26552655
case ActorIsolationRestriction::ActorSelf: {
26562656
// Actor-isolated witnesses cannot conform to protocol requirements.
2657-
bool canBeAsyncHandler = false;
2657+
witness->diagnose(diag::actor_isolated_witness,
2658+
witness->getDescriptiveKind(),
2659+
witness->getName());
26582660
if (auto witnessFunc = dyn_cast<FuncDecl>(witness)) {
2659-
canBeAsyncHandler = !witnessFunc->isAsyncHandler() &&
26602661
witnessFunc->canBeAsyncHandler();
2662+
if (!witnessFunc->isAsyncHandler()) {
2663+
auto handlerNote = witness->diagnose(
2664+
diag::note_add_asynchandler_to_function,
2665+
witness->getName());
2666+
handlerNote.fixItInsert(witness->getAttributeInsertionLoc(false),
2667+
"@asyncHandler ");
2668+
}
26612669
}
2662-
auto diag = witness->diagnose(
2663-
canBeAsyncHandler
2664-
? diag::actor_isolated_witness_could_be_async_handler
2665-
: diag::actor_isolated_witness,
2666-
witness->getDescriptiveKind(), witness->getName());
2667-
2668-
if (canBeAsyncHandler) {
2669-
diag.fixItInsert(
2670-
witness->getAttributeInsertionLoc(false), "@asyncHandler ");
2670+
2671+
{
2672+
auto witnessVar = dyn_cast<VarDecl>(witness);
2673+
if ((witnessVar && !witnessVar->hasStorage()) || !witnessVar) {
2674+
auto independentNote = witness->diagnose(
2675+
diag::note_add_actorindependent_to_decl,
2676+
witness->getName(), witness->getDescriptiveKind());
2677+
independentNote.fixItInsert(witness->getAttributeInsertionLoc(false),
2678+
"@actorIndependent ");
2679+
}
26712680
}
26722681

26732682
return true;

test/decl/class/actor/conformance.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ actor class OtherActor: SyncProtocol {
3737

3838
var propertyA: Int { 17 }
3939
// expected-error@-1{{actor-isolated property 'propertyA' cannot be used to satisfy a protocol requirement}}
40+
// expected-note@-2{{add '@actorIndependent' to 'propertyA' to make this property independent of the actor}}{{3-3=@actorIndependent }}
4041

4142
func syncMethodA() { }
42-
// expected-error@-1{{actor-isolated instance method 'syncMethodA()' cannot be used to satisfy a protocol requirement; did you mean to make it an asychronous handler?}}{{3-3=@asyncHandler }}
43+
// expected-error@-1{{actor-isolated instance method 'syncMethodA()' cannot be used to satisfy a protocol requirement}}
44+
// expected-note@-2{{add '@actorIndependent' to 'syncMethodA()' to make this instance method independent of the actor}}{{3-3=@actorIndependent }}
45+
// expected-note@-3{{add '@asyncHandler' to function 'syncMethodA()' to create an implicit asynchronous context}}{{3-3=@asyncHandler }}
4346

4447
// Async handlers are okay.
4548
@asyncHandler
@@ -51,6 +54,7 @@ actor class OtherActor: SyncProtocol {
5154

5255
subscript (index: Int) -> String { "\(index)" }
5356
// expected-error@-1{{actor-isolated subscript 'subscript(_:)' cannot be used to satisfy a protocol requirement}}
57+
// expected-note@-2{{add '@actorIndependent' to 'subscript(_:)' to make this subscript independent of the actor}}{{3-3=@actorIndependent }}
5458

5559
// Static methods and properties are okay.
5660
static func staticMethod() { }

test/decl/protocol/special/Actor.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ class C1: Actor {
4141

4242
// Method that is not usable as a witness.
4343
actor class BA1 {
44-
func enqueue(partialTask: PartialAsyncTask) { } // expected-error{{actor-isolated instance method 'enqueue(partialTask:)' cannot be used to satisfy a protocol requirement; did you mean to make it an asychronous handler?}}
44+
func enqueue(partialTask: PartialAsyncTask) { } // expected-error{{actor-isolated instance method 'enqueue(partialTask:)' cannot be used to satisfy a protocol requirement}}
45+
//expected-note@-1{{add '@asyncHandler' to function 'enqueue(partialTask:)' to create an implicit asynchronous context}}{{3-3=@asyncHandler }}
46+
//expected-note@-2{{add '@actorIndependent' to 'enqueue(partialTask:)' to make this instance method independent of the actor}}{{3-3=@actorIndependent }}
4547
}
4648

4749
// Method that isn't part of the main class definition cannot be used to

0 commit comments

Comments
 (0)