Skip to content

Commit 9c983a4

Browse files
committed
[Concurrency] Rename IsolationRestriction and use it more widely.
Rename IsolationRestriction to ActorIsolationRestriction. This type governs the *use* of a potentially actor-isolated entity, which includes the notion that (e.g.) an asychronous function can be used from any context even when it is actor-isolated. Use this for @objc checking and protocol conformance checking, in addition to its original use for enforcing actor isolation in statements and expressions.
1 parent c6f4be2 commit 9c983a4

File tree

4 files changed

+201
-208
lines changed

4 files changed

+201
-208
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 81 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -402,188 +402,86 @@ GlobalActorAttributeRequest::evaluate(
402402
return std::make_pair(globalActorAttr, globalActorNominal);
403403
}
404404

405-
namespace {
406-
407-
/// The isolation restriction in effect for a given declaration that is
408-
/// referenced from source.
409-
class IsolationRestriction {
410-
public:
411-
enum Kind {
412-
/// There is no restriction on references to the given declaration,
413-
/// e.g., because it's immutable.
414-
Unrestricted,
415-
416-
/// Access to the declaration is unsafe in a concurrent context.
417-
Unsafe,
418-
419-
/// The declaration is a local entity whose capture could introduce
420-
/// data races. The context in which the local was defined is provided.
421-
LocalCapture,
422-
423-
/// References to this member of an actor are only permitted on 'self'.
424-
ActorSelf,
425-
426-
/// References to a declaration that is part of a global actor are only
427-
/// permitted from other declarations with that same global actor.
428-
GlobalActor,
429-
};
430-
431-
private:
432-
/// The kind of restriction
433-
Kind kind;
434-
435-
union {
436-
/// The local context that an entity is tied to.
437-
DeclContext *localContext;
438-
439-
/// The actor class that the entity is declared in.
440-
ClassDecl *actorClass;
441-
442-
/// The global actor type.
443-
TypeBase *globalActor;
444-
} data;
445-
446-
explicit IsolationRestriction(Kind kind) : kind(kind) { }
447-
448-
public:
449-
Kind getKind() const { return kind; }
450-
451-
/// Retrieve the declaration context in which a local was defined.
452-
DeclContext *getLocalContext() const {
453-
assert(kind == LocalCapture);
454-
return data.localContext;
455-
}
456-
457-
/// Retrieve the actor class that the declaration is within.
458-
ClassDecl *getActorClass() const {
459-
assert(kind == ActorSelf);
460-
return data.actorClass;
461-
}
462-
463-
/// Retrieve the actor class that the declaration is within.
464-
Type getGlobalActor() const {
465-
assert(kind == GlobalActor);
466-
return Type(data.globalActor);
467-
}
468-
469-
/// There are no restrictions on the use of the entity.
470-
static IsolationRestriction forUnrestricted() {
471-
return IsolationRestriction(Unrestricted);
472-
}
473-
474-
/// Accesses to the given declaration are unsafe.
475-
static IsolationRestriction forUnsafe() {
476-
return IsolationRestriction(Unsafe);
477-
}
478-
479-
/// Accesses to the given declaration can only be made via the 'self' of
480-
/// the current actor.
481-
static IsolationRestriction forActorSelf(ClassDecl *actorClass) {
482-
IsolationRestriction result(ActorSelf);
483-
result.data.actorClass = actorClass;
484-
return result;
485-
}
486-
487-
/// Access is restricted to code running within the given local context.
488-
static IsolationRestriction forLocalCapture(DeclContext *dc) {
489-
IsolationRestriction result(LocalCapture);
490-
result.data.localContext = dc;
491-
return result;
492-
}
493-
494-
/// Accesses to the given declaration can only be made via this particular
495-
/// global actor.
496-
static IsolationRestriction forGlobalActor(Type globalActor) {
497-
IsolationRestriction result(GlobalActor);
498-
result.data.globalActor = globalActor.getPointer();
499-
return result;
500-
}
501-
502-
/// Determine the isolation rules for a given declaration.
503-
static IsolationRestriction forDeclaration(Decl *decl) {
504-
switch (decl->getKind()) {
505-
case DeclKind::AssociatedType:
506-
case DeclKind::Class:
507-
case DeclKind::Enum:
508-
case DeclKind::Extension:
509-
case DeclKind::GenericTypeParam:
510-
case DeclKind::OpaqueType:
511-
case DeclKind::Protocol:
512-
case DeclKind::Struct:
513-
case DeclKind::TypeAlias:
514-
// Types are always available.
515-
return forUnrestricted();
516-
517-
case DeclKind::Constructor:
518-
case DeclKind::EnumCase:
519-
case DeclKind::EnumElement:
520-
// Type-level entities don't require isolation.
521-
return forUnrestricted();
522-
523-
case DeclKind::IfConfig:
524-
case DeclKind::Import:
525-
case DeclKind::InfixOperator:
526-
case DeclKind::MissingMember:
527-
case DeclKind::Module:
528-
case DeclKind::PatternBinding:
529-
case DeclKind::PostfixOperator:
530-
case DeclKind::PoundDiagnostic:
531-
case DeclKind::PrecedenceGroup:
532-
case DeclKind::PrefixOperator:
533-
case DeclKind::TopLevelCode:
534-
// Non-value entities don't require isolation.
405+
/// Determine the isolation rules for a given declaration.
406+
ActorIsolationRestriction ActorIsolationRestriction::forDeclaration(Decl *decl) {
407+
switch (decl->getKind()) {
408+
case DeclKind::AssociatedType:
409+
case DeclKind::Class:
410+
case DeclKind::Enum:
411+
case DeclKind::Extension:
412+
case DeclKind::GenericTypeParam:
413+
case DeclKind::OpaqueType:
414+
case DeclKind::Protocol:
415+
case DeclKind::Struct:
416+
case DeclKind::TypeAlias:
417+
// Types are always available.
418+
return forUnrestricted();
419+
420+
case DeclKind::Constructor:
421+
case DeclKind::EnumCase:
422+
case DeclKind::EnumElement:
423+
// Type-level entities don't require isolation.
424+
return forUnrestricted();
425+
426+
case DeclKind::IfConfig:
427+
case DeclKind::Import:
428+
case DeclKind::InfixOperator:
429+
case DeclKind::MissingMember:
430+
case DeclKind::Module:
431+
case DeclKind::PatternBinding:
432+
case DeclKind::PostfixOperator:
433+
case DeclKind::PoundDiagnostic:
434+
case DeclKind::PrecedenceGroup:
435+
case DeclKind::PrefixOperator:
436+
case DeclKind::TopLevelCode:
437+
// Non-value entities don't require isolation.
438+
return forUnrestricted();
439+
440+
case DeclKind::Destructor:
441+
// Destructors don't require isolation.
442+
return forUnrestricted();
443+
444+
case DeclKind::Param:
445+
case DeclKind::Var:
446+
// 'let' declarations are immutable, so there are no restrictions on
447+
// their access.
448+
if (cast<VarDecl>(decl)->isLet())
535449
return forUnrestricted();
536450

537-
case DeclKind::Destructor:
538-
// Destructors don't require isolation.
539-
return forUnrestricted();
451+
LLVM_FALLTHROUGH;
540452

541-
case DeclKind::Param:
542-
case DeclKind::Var:
543-
// 'let' declarations are immutable, so there are no restrictions on
544-
// their access.
545-
if (cast<VarDecl>(decl)->isLet())
453+
case DeclKind::Accessor:
454+
case DeclKind::Func:
455+
case DeclKind::Subscript:
456+
// A function that provides an asynchronous context has no restrictions
457+
// on its access.
458+
if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
459+
if (func->isAsyncContext())
546460
return forUnrestricted();
461+
}
547462

548-
LLVM_FALLTHROUGH;
549-
550-
case DeclKind::Accessor:
551-
case DeclKind::Func:
552-
case DeclKind::Subscript:
553-
// A function that provides an asynchronous context has no restrictions
554-
// on its access.
555-
if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
556-
if (func->isAsyncContext())
557-
return forUnrestricted();
558-
}
559-
560-
// Local captures can only be referenced in their local context or a
561-
// context that is guaranteed not to run concurrently with it.
562-
if (cast<ValueDecl>(decl)->isLocalCapture())
563-
return forLocalCapture(decl->getDeclContext());
463+
// Local captures can only be referenced in their local context or a
464+
// context that is guaranteed not to run concurrently with it.
465+
if (cast<ValueDecl>(decl)->isLocalCapture())
466+
return forLocalCapture(decl->getDeclContext());
564467

565-
// Determine the actor isolation of the given declaration.
566-
switch (auto isolation = getActorIsolation(cast<ValueDecl>(decl))) {
567-
case ActorIsolation::ActorInstance:
568-
// Protected actor instance members can only be accessed on 'self'.
569-
return forActorSelf(isolation.getActor());
468+
// Determine the actor isolation of the given declaration.
469+
switch (auto isolation = getActorIsolation(cast<ValueDecl>(decl))) {
470+
case ActorIsolation::ActorInstance:
471+
// Protected actor instance members can only be accessed on 'self'.
472+
return forActorSelf(isolation.getActor());
570473

571-
case ActorIsolation::GlobalActor:
572-
return forGlobalActor(isolation.getGlobalActor());
474+
case ActorIsolation::GlobalActor:
475+
return forGlobalActor(isolation.getGlobalActor());
573476

574-
case ActorIsolation::Independent:
575-
// Actor-independent have no restrictions on their access.
576-
return forUnrestricted();
477+
case ActorIsolation::Independent:
478+
// Actor-independent have no restrictions on their access.
479+
return forUnrestricted();
577480

578-
case ActorIsolation::Unspecified:
579-
return forUnsafe();
580-
}
481+
case ActorIsolation::Unspecified:
482+
return forUnsafe();
581483
}
582484
}
583-
584-
operator Kind() const { return kind; };
585-
};
586-
587485
}
588486

589487
namespace {
@@ -910,18 +808,18 @@ void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
910808
if (!value)
911809
return false;
912810

913-
switch (auto isolation = IsolationRestriction::forDeclaration(value)) {
914-
case IsolationRestriction::Unrestricted:
811+
switch (auto isolation = ActorIsolationRestriction::forDeclaration(value)) {
812+
case ActorIsolationRestriction::Unrestricted:
915813
return false;
916814

917-
case IsolationRestriction::ActorSelf:
815+
case ActorIsolationRestriction::ActorSelf:
918816
llvm_unreachable("non-member reference into an actor");
919817

920-
case IsolationRestriction::GlobalActor:
818+
case ActorIsolationRestriction::GlobalActor:
921819
return checkGlobalActorReference(
922820
value, loc, isolation.getGlobalActor());
923821

924-
case IsolationRestriction::LocalCapture:
822+
case ActorIsolationRestriction::LocalCapture:
925823
// Only diagnose unsafe concurrent accesses within the context of an
926824
// actor. This is globally unsafe, but locally enforceable.
927825
if (!getNearestEnclosingActorContext(getDeclContext()))
@@ -941,7 +839,7 @@ void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
941839

942840
return false;
943841

944-
case IsolationRestriction::Unsafe:
842+
case ActorIsolationRestriction::Unsafe:
945843
return diagnoseReferenceToUnsafe(value, loc);
946844
}
947845
}
@@ -953,11 +851,11 @@ void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
953851
if (!base || !member)
954852
return false;
955853

956-
switch (auto isolation = IsolationRestriction::forDeclaration(member)) {
957-
case IsolationRestriction::Unrestricted:
854+
switch (auto isolation = ActorIsolationRestriction::forDeclaration(member)) {
855+
case ActorIsolationRestriction::Unrestricted:
958856
return false;
959857

960-
case IsolationRestriction::ActorSelf: {
858+
case ActorIsolationRestriction::ActorSelf: {
961859
// Must reference actor-isolated state on 'self'.
962860
auto selfVar = getSelfReference(base);
963861
if (!selfVar) {
@@ -1028,14 +926,14 @@ void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
1028926
return false;
1029927
}
1030928

1031-
case IsolationRestriction::GlobalActor:
929+
case ActorIsolationRestriction::GlobalActor:
1032930
return checkGlobalActorReference(
1033931
member, memberLoc, isolation.getGlobalActor());
1034932

1035-
case IsolationRestriction::LocalCapture:
933+
case ActorIsolationRestriction::LocalCapture:
1036934
llvm_unreachable("Locals cannot be referenced with member syntax");
1037935

1038-
case IsolationRestriction::Unsafe:
936+
case ActorIsolationRestriction::Unsafe:
1039937
return diagnoseReferenceToUnsafe(member, memberLoc);
1040938
}
1041939
}

0 commit comments

Comments
 (0)