Skip to content

Commit 863fdf9

Browse files
committed
Simplify @objc checking for actor-isolated members.
(cherry picked from commit 58382a8)
1 parent b7015c8 commit 863fdf9

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
@@ -1651,10 +1651,6 @@ static void noteGlobalActorOnContext(DeclContext *dc, Type globalActor) {
16511651
}
16521652
}
16531653

1654-
static bool isAccessibleAcrossActors(
1655-
ValueDecl *value, const ActorIsolation &isolation,
1656-
const DeclContext *fromDC, Optional<ReferencedActor> actorInstance);
1657-
16581654
namespace {
16591655
/// Check for adherence to the actor isolation rules, emitting errors
16601656
/// when actor-isolated declarations are used in an unsafe manner.
@@ -4917,13 +4913,7 @@ static bool isThrowsDecl(ConcreteDeclRef declRef) {
49174913
return false;
49184914
}
49194915

4920-
/// Determine whether the given value can be accessed across actors
4921-
/// without from normal synchronous code.
4922-
///
4923-
/// \param value The value we are checking.
4924-
/// \param isolation The actor isolation of the value.
4925-
/// \param fromDC The context where we are performing the access.
4926-
static bool isAccessibleAcrossActors(
4916+
bool swift::isAccessibleAcrossActors(
49274917
ValueDecl *value, const ActorIsolation &isolation,
49284918
const DeclContext *fromDC, Optional<ReferencedActor> actorInstance) {
49294919
switch (value->getKind()) {

lib/Sema/TypeCheckConcurrency.h

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

570+
/// Determine whether the given value can be accessed across actors
571+
/// without from normal synchronous code.
572+
///
573+
/// \param value The value we are checking.
574+
/// \param isolation The actor isolation of the value.
575+
/// \param fromDC The context where we are performing the access.
576+
bool isAccessibleAcrossActors(
577+
ValueDecl *value, const ActorIsolation &isolation,
578+
const DeclContext *fromDC, Optional<ReferencedActor> actorInstance = None);
579+
570580
/// Check whether given variable references to a potentially
571581
/// isolated actor.
572582
bool isPotentiallyIsolatedActor(

lib/Sema/TypeCheckDeclObjC.cpp

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

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

452-
case ActorIsolationRestriction::GlobalActorUnsafe:
453-
case ActorIsolationRestriction::GlobalActor:
466+
case ActorIsolation::GlobalActor:
467+
case ActorIsolation::GlobalActorUnsafe:
454468
// FIXME: Consider whether to limit @objc on global-actor-qualified
455-
// declarations.
456-
case ActorIsolationRestriction::Unrestricted:
457-
case ActorIsolationRestriction::Unsafe:
469+
// declarations. Perhaps only allow main actor, which we can reflect
470+
// in the generated header.
471+
return false;
472+
473+
case ActorIsolation::Independent:
474+
case ActorIsolation::Unspecified:
458475
return false;
459476
}
460477
}

0 commit comments

Comments
 (0)