Skip to content

Commit 58382a8

Browse files
committed
Simplify @objc checking for actor-isolated members.
1 parent 29656b8 commit 58382a8

File tree

3 files changed

+48
-31
lines changed

3 files changed

+48
-31
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,10 +1597,6 @@ static void noteGlobalActorOnContext(DeclContext *dc, Type globalActor) {
15971597
}
15981598
}
15991599

1600-
static bool isAccessibleAcrossActors(
1601-
ValueDecl *value, const ActorIsolation &isolation,
1602-
const DeclContext *fromDC, Optional<ReferencedActor> actorInstance);
1603-
16041600
namespace {
16051601
/// Check for adherence to the actor isolation rules, emitting errors
16061602
/// when actor-isolated declarations are used in an unsafe manner.
@@ -4847,13 +4843,7 @@ static bool isThrowsDecl(ConcreteDeclRef declRef) {
48474843
return false;
48484844
}
48494845

4850-
/// Determine whether the given value can be accessed across actors
4851-
/// without from normal synchronous code.
4852-
///
4853-
/// \param value The value we are checking.
4854-
/// \param isolation The actor isolation of the value.
4855-
/// \param fromDC The context where we are performing the access.
4856-
static bool isAccessibleAcrossActors(
4846+
bool swift::isAccessibleAcrossActors(
48574847
ValueDecl *value, const ActorIsolation &isolation,
48584848
const DeclContext *fromDC, Optional<ReferencedActor> actorInstance) {
48594849
switch (value->getKind()) {

lib/Sema/TypeCheckConcurrency.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,16 @@ VarDecl *getReferencedParamOrCapture(
542542
Expr *expr,
543543
llvm::function_ref<Expr *(OpaqueValueExpr *)> getExistentialValue);
544544

545+
/// Determine whether the given value can be accessed across actors
546+
/// without from normal synchronous code.
547+
///
548+
/// \param value The value we are checking.
549+
/// \param isolation The actor isolation of the value.
550+
/// \param fromDC The context where we are performing the access.
551+
bool isAccessibleAcrossActors(
552+
ValueDecl *value, const ActorIsolation &isolation,
553+
const DeclContext *fromDC, Optional<ReferencedActor> actorInstance = None);
554+
545555
/// Check whether given variable references to a potentially
546556
/// isolated actor.
547557
bool isPotentiallyIsolatedActor(

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -428,35 +428,52 @@ static bool checkObjCInForeignClassContext(const ValueDecl *VD,
428428
return true;
429429
}
430430

431+
/// Whether the given declaration can be exposed as Objective-C.
432+
static bool canExposeActorIsolatedAsObjC(
433+
const ValueDecl *value, const ActorIsolation &isolation) {
434+
if (isAccessibleAcrossActors(
435+
const_cast<ValueDecl *>(value), isolation, value->getDeclContext()))
436+
return true;
437+
438+
// An async function can be exposed as Objective-C.
439+
if (auto func = dyn_cast<AbstractFunctionDecl>( value))
440+
return func->hasAsync();
441+
442+
return false;
443+
}
444+
431445
/// Actor-isolated declarations cannot be @objc.
432-
static bool checkObjCActorIsolation(const ValueDecl *VD,
433-
ObjCReason Reason) {
446+
static bool checkObjCActorIsolation(const ValueDecl *VD, ObjCReason Reason) {
434447
// Check actor isolation.
435-
switch (auto restriction = ActorIsolationRestriction::forDeclaration(
436-
const_cast<ValueDecl *>(VD), VD->getDeclContext(),
437-
/*fromExpression=*/false)) {
438-
case ActorIsolationRestriction::CrossActorSelf:
448+
switch (auto isolation = getActorIsolation(const_cast<ValueDecl *>(VD))) {
449+
case ActorIsolation::ActorInstance:
450+
if (!canExposeActorIsolatedAsObjC(VD, isolation)) {
451+
// Actor-isolated functions cannot be @objc.
452+
VD->diagnose(diag::actor_isolated_objc, VD->getDescriptiveKind(),
453+
VD->getName());
454+
Reason.describe(VD);
455+
if (auto FD = dyn_cast<FuncDecl>(VD)) {
456+
addAsyncNotes(const_cast<FuncDecl *>(FD));
457+
}
458+
459+
return true;
460+
}
461+
439462
// FIXME: Substitution map?
440463
diagnoseNonSendableTypesInReference(
441464
const_cast<ValueDecl *>(VD), VD->getDeclContext(),
442465
VD->getLoc(), SendableCheckReason::ObjC);
443466
return false;
444-
case ActorIsolationRestriction::ActorSelf:
445-
// Actor-isolated functions cannot be @objc.
446-
VD->diagnose(diag::actor_isolated_objc, VD->getDescriptiveKind(),
447-
VD->getName());
448-
Reason.describe(VD);
449-
if (auto FD = dyn_cast<FuncDecl>(VD)) {
450-
addAsyncNotes(const_cast<FuncDecl *>(FD));
451-
}
452-
return true;
453467

454-
case ActorIsolationRestriction::GlobalActorUnsafe:
455-
case ActorIsolationRestriction::GlobalActor:
468+
case ActorIsolation::GlobalActor:
469+
case ActorIsolation::GlobalActorUnsafe:
456470
// FIXME: Consider whether to limit @objc on global-actor-qualified
457-
// declarations.
458-
case ActorIsolationRestriction::Unrestricted:
459-
case ActorIsolationRestriction::Unsafe:
471+
// declarations. Perhaps only allow main actor, which we can reflect
472+
// in the generated header.
473+
return false;
474+
475+
case ActorIsolation::Independent:
476+
case ActorIsolation::Unspecified:
460477
return false;
461478
}
462479
}

0 commit comments

Comments
 (0)