Skip to content

Commit 342bbd3

Browse files
authored
Merge pull request #79087 from gottesmm/actor-isolation-refactoring
[concurrency] Introduce concurrent, swap its meaning with nonisolated and make nonisolated caller inheriting isolation.
2 parents d450bda + 9c328a8 commit 342bbd3

39 files changed

+395
-331
lines changed

include/swift/AST/ActorIsolation.h

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,19 @@ class ActorIsolation {
5757
/// the actor is isolated to the instance of that actor.
5858
ActorInstance,
5959
/// The declaration is explicitly specified to be not isolated to any actor,
60-
/// meaning that it can be used from any actor but is also unable to
61-
/// refer to the isolated state of any given actor.
60+
/// meaning it cannot itself access actor isolated state but /does/ allow
61+
/// for indirect access to actor isolated state if the declaration can
62+
/// guarantee that all code generated to work with the declaration will run
63+
/// on said actor.
64+
///
65+
/// E.x.: a nonisolated function can accept actor-isolated values as
66+
/// arguments since the caller knows that it will not escape the values to
67+
/// another isolation domain and that the function will remain on the
68+
/// caller's actor.
69+
///
70+
/// NOTE: This used to have the meaning of Concurrent which is a stricter
71+
/// definition of nonisolated that prevents the code generated to work with
72+
/// the declaration to never touch actor isolated state.
6273
Nonisolated,
6374
/// The declaration is explicitly specified to be not isolated and with the
6475
/// "unsafe" annotation, which means that we do not enforce isolation.
@@ -69,11 +80,20 @@ class ActorIsolation {
6980
/// The actor isolation iss statically erased, as for a call to
7081
/// an isolated(any) function. This is not possible for declarations.
7182
Erased,
72-
/// Inherits isolation from the caller of the given function.
83+
/// The declaration is explicitly specified to be not isolated to any actor,
84+
/// meaning that it can be used from any actor but is also unable to
85+
/// refer to the isolated state of any given actor.
7386
///
74-
/// DISCUSSION: This is used for nonisolated asynchronous functions that we
75-
/// want to inherit from their context the context's actor isolation.
76-
CallerIsolationInheriting,
87+
/// NOTE: This used to be nonisolated, but we changed nonisolated to have a
88+
/// weaker definition of nonisolated that allows for actor isolated state to
89+
/// be manipulated by code generated to work with the actor as long as all
90+
/// such code generation is guaranteed to always run on whatever actor
91+
/// isolation it is invoked in consistently and not escape the value to any
92+
/// other isolation domain.
93+
Concurrent,
94+
/// The declaration is explicitly specified to be concurrent and with the
95+
/// "unsafe" annotation, which means that we do not enforce isolation.
96+
ConcurrentUnsafe,
7797
};
7898

7999
private:
@@ -88,7 +108,7 @@ class ActorIsolation {
88108
/// Set to true if this was parsed from SIL.
89109
unsigned silParsed : 1;
90110

91-
unsigned parameterIndex : 27;
111+
unsigned parameterIndex : 26;
92112

93113
ActorIsolation(Kind kind, NominalTypeDecl *actor, unsigned parameterIndex);
94114

@@ -112,10 +132,8 @@ class ActorIsolation {
112132
return ActorIsolation(unsafe ? NonisolatedUnsafe : Nonisolated);
113133
}
114134

115-
static ActorIsolation forCallerIsolationInheriting() {
116-
// NOTE: We do not use parameter indices since the parameter is implicit
117-
// from the perspective of the AST.
118-
return ActorIsolation(CallerIsolationInheriting);
135+
static ActorIsolation forConcurrent(bool unsafe) {
136+
return ActorIsolation(unsafe ? ConcurrentUnsafe : Concurrent);
119137
}
120138

121139
static ActorIsolation forActorInstanceSelf(ValueDecl *decl);
@@ -165,9 +183,10 @@ class ActorIsolation {
165183
std::optional<ActorIsolation>(ActorIsolation::GlobalActor))
166184
.Case("global_actor_unsafe",
167185
std::optional<ActorIsolation>(ActorIsolation::GlobalActor))
168-
.Case("caller_isolation_inheriting",
169-
std::optional<ActorIsolation>(
170-
ActorIsolation::CallerIsolationInheriting))
186+
.Case("concurrent",
187+
std::optional<ActorIsolation>(ActorIsolation::Concurrent))
188+
.Case("concurrent_unsafe", std::optional<ActorIsolation>(
189+
ActorIsolation::ConcurrentUnsafe))
171190
.Default(std::nullopt);
172191
if (kind == std::nullopt)
173192
return std::nullopt;
@@ -180,11 +199,17 @@ class ActorIsolation {
180199

181200
bool isUnspecified() const { return kind == Unspecified; }
182201

202+
bool isConcurrent() const {
203+
return (kind == Concurrent) || (kind == ConcurrentUnsafe);
204+
}
205+
183206
bool isNonisolated() const {
184207
return (kind == Nonisolated) || (kind == NonisolatedUnsafe);
185208
}
186209

187-
bool isNonisolatedUnsafe() const { return kind == NonisolatedUnsafe; }
210+
bool isUnsafe() const {
211+
return kind == NonisolatedUnsafe || kind == ConcurrentUnsafe;
212+
}
188213

189214
/// Retrieve the parameter to which actor-instance isolation applies.
190215
///
@@ -212,7 +237,8 @@ class ActorIsolation {
212237
case Unspecified:
213238
case Nonisolated:
214239
case NonisolatedUnsafe:
215-
case CallerIsolationInheriting:
240+
case Concurrent:
241+
case ConcurrentUnsafe:
216242
return false;
217243
}
218244
}

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3844,18 +3844,19 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, Label>,
38443844
switch (auto isolation = E->getActorIsolation()) {
38453845
case ActorIsolation::Unspecified:
38463846
case ActorIsolation::NonisolatedUnsafe:
3847+
case ActorIsolation::ConcurrentUnsafe:
38473848
break;
38483849

38493850
case ActorIsolation::Nonisolated:
38503851
printFlag(true, "nonisolated", CapturesColor);
38513852
break;
38523853

3853-
case ActorIsolation::Erased:
3854-
printFlag(true, "dynamically_isolated", CapturesColor);
3854+
case ActorIsolation::Concurrent:
3855+
printFlag(true, "concurrent", CapturesColor);
38553856
break;
38563857

3857-
case ActorIsolation::CallerIsolationInheriting:
3858-
printFlag(true, "isolated_to_caller_isolation", CapturesColor);
3858+
case ActorIsolation::Erased:
3859+
printFlag(true, "dynamically_isolated", CapturesColor);
38593860
break;
38603861

38613862
case ActorIsolation::ActorInstance:

lib/AST/ActorIsolation.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ ActorIsolation::ActorIsolation(Kind kind, Expr *actor, unsigned parameterIndex)
3939

4040
ActorIsolation::ActorIsolation(Kind kind, Type globalActor)
4141
: globalActor(globalActor), kind(kind), isolatedByPreconcurrency(false),
42-
silParsed(false), parameterIndex(0) {}
42+
silParsed(false), parameterIndex(0) {
43+
assert((silParsed || globalActor) &&
44+
"If we are not sil parsed, global actor must be a real type");
45+
}
4346

4447
ActorIsolation
4548
ActorIsolation::forActorInstanceParameter(Expr *actor,
@@ -49,7 +52,7 @@ ActorIsolation::forActorInstanceParameter(Expr *actor,
4952
// An isolated value of `nil` is statically nonisolated.
5053
// FIXME: Also allow 'Optional.none'
5154
if (isa<NilLiteralExpr>(actor))
52-
return ActorIsolation::forNonisolated(/*unsafe*/ false);
55+
return ActorIsolation::forConcurrent(/*unsafe*/ false);
5356

5457
// An isolated value of `<global actor type>.shared` is statically
5558
// global actor isolated.
@@ -162,8 +165,8 @@ bool ActorIsolation::isEqual(const ActorIsolation &lhs,
162165
return false;
163166

164167
switch (lhs.getKind()) {
165-
case Nonisolated:
166-
case NonisolatedUnsafe:
168+
case Concurrent:
169+
case ConcurrentUnsafe:
167170
case Unspecified:
168171
return true;
169172

@@ -174,7 +177,8 @@ bool ActorIsolation::isEqual(const ActorIsolation &lhs,
174177
// to answer.
175178
return false;
176179

177-
case CallerIsolationInheriting:
180+
case Nonisolated:
181+
case NonisolatedUnsafe:
178182
// This returns false for the same reason as erased. The caller has to check
179183
// against the actual caller isolation.
180184
return false;

lib/AST/Decl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,7 @@ static bool deferMatchesEnclosingAccess(const FuncDecl *defer) {
27572757
switch (isolation) {
27582758
case ActorIsolation::Unspecified:
27592759
case ActorIsolation::NonisolatedUnsafe:
2760+
case ActorIsolation::ConcurrentUnsafe:
27602761
break;
27612762

27622763
case ActorIsolation::GlobalActor:
@@ -2765,9 +2766,9 @@ static bool deferMatchesEnclosingAccess(const FuncDecl *defer) {
27652766

27662767
return true;
27672768

2768-
case ActorIsolation::CallerIsolationInheriting:
27692769
case ActorIsolation::ActorInstance:
27702770
case ActorIsolation::Nonisolated:
2771+
case ActorIsolation::Concurrent:
27712772
case ActorIsolation::Erased: // really can't happen
27722773
return true;
27732774
}
@@ -11461,9 +11462,10 @@ bool VarDecl::isSelfParamCaptureIsolated() const {
1146111462
case ActorIsolation::Unspecified:
1146211463
case ActorIsolation::Nonisolated:
1146311464
case ActorIsolation::NonisolatedUnsafe:
11465+
case ActorIsolation::Concurrent:
11466+
case ActorIsolation::ConcurrentUnsafe:
1146411467
case ActorIsolation::GlobalActor:
1146511468
case ActorIsolation::Erased:
11466-
case ActorIsolation::CallerIsolationInheriting:
1146711469
return false;
1146811470

1146911471
case ActorIsolation::ActorInstance:

lib/AST/TypeCheckRequests.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,10 +1856,11 @@ SourceLoc MacroDefinitionRequest::getNearestLoc() const {
18561856

18571857
bool ActorIsolation::requiresSubstitution() const {
18581858
switch (kind) {
1859-
case CallerIsolationInheriting:
18601859
case ActorInstance:
18611860
case Nonisolated:
18621861
case NonisolatedUnsafe:
1862+
case Concurrent:
1863+
case ConcurrentUnsafe:
18631864
case Unspecified:
18641865
return false;
18651866

@@ -1872,9 +1873,10 @@ bool ActorIsolation::requiresSubstitution() const {
18721873
ActorIsolation ActorIsolation::subst(SubstitutionMap subs) const {
18731874
switch (kind) {
18741875
case ActorInstance:
1875-
case CallerIsolationInheriting:
18761876
case Nonisolated:
18771877
case NonisolatedUnsafe:
1878+
case Concurrent:
1879+
case ConcurrentUnsafe:
18781880
case Unspecified:
18791881
return *this;
18801882

@@ -1893,11 +1895,6 @@ void ActorIsolation::printForDiagnostics(llvm::raw_ostream &os,
18931895
os << "actor" << (asNoun ? " isolation" : "-isolated");
18941896
break;
18951897

1896-
case ActorIsolation::CallerIsolationInheriting:
1897-
os << "caller isolation inheriting"
1898-
<< (asNoun ? " isolation" : "-isolated");
1899-
break;
1900-
19011898
case ActorIsolation::GlobalActor: {
19021899
if (isMainActor()) {
19031900
os << "main actor" << (asNoun ? " isolation" : "-isolated");
@@ -1912,11 +1909,13 @@ void ActorIsolation::printForDiagnostics(llvm::raw_ostream &os,
19121909
os << "@isolated(any)";
19131910
break;
19141911

1912+
case ActorIsolation::Concurrent:
1913+
case ActorIsolation::ConcurrentUnsafe:
19151914
case ActorIsolation::Nonisolated:
19161915
case ActorIsolation::NonisolatedUnsafe:
19171916
case ActorIsolation::Unspecified:
19181917
os << "nonisolated";
1919-
if (*this == ActorIsolation::NonisolatedUnsafe) {
1918+
if (isUnsafe()) {
19201919
os << "(unsafe)";
19211920
}
19221921
break;
@@ -1934,15 +1933,18 @@ void ActorIsolation::print(llvm::raw_ostream &os) const {
19341933
os << ". name: '" << vd->getBaseIdentifier() << "'";
19351934
}
19361935
return;
1937-
case CallerIsolationInheriting:
1938-
os << "caller_isolation_inheriting";
1939-
return;
19401936
case Nonisolated:
19411937
os << "nonisolated";
19421938
return;
19431939
case NonisolatedUnsafe:
19441940
os << "nonisolated_unsafe";
19451941
return;
1942+
case Concurrent:
1943+
os << "concurrent";
1944+
return;
1945+
case ConcurrentUnsafe:
1946+
os << "concurrent_unsafe";
1947+
return;
19461948
case GlobalActor:
19471949
os << "global_actor. type: " << getGlobalActor();
19481950
return;
@@ -1961,15 +1963,18 @@ void ActorIsolation::printForSIL(llvm::raw_ostream &os) const {
19611963
case ActorInstance:
19621964
os << "actor_instance";
19631965
return;
1964-
case CallerIsolationInheriting:
1965-
os << "caller_isolation_inheriting";
1966-
return;
19671966
case Nonisolated:
19681967
os << "nonisolated";
19691968
return;
19701969
case NonisolatedUnsafe:
19711970
os << "nonisolated_unsafe";
19721971
return;
1972+
case Concurrent:
1973+
os << "concurrent";
1974+
return;
1975+
case ConcurrentUnsafe:
1976+
os << "concurrent_unsafe";
1977+
return;
19731978
case GlobalActor:
19741979
os << "global_actor";
19751980
return;
@@ -2009,14 +2014,12 @@ void swift::simple_display(
20092014
}
20102015
break;
20112016

2012-
case ActorIsolation::CallerIsolationInheriting:
2013-
out << "isolated to isolation of caller";
2014-
break;
2015-
20162017
case ActorIsolation::Nonisolated:
20172018
case ActorIsolation::NonisolatedUnsafe:
2019+
case ActorIsolation::Concurrent:
2020+
case ActorIsolation::ConcurrentUnsafe:
20182021
out << "nonisolated";
2019-
if (state == ActorIsolation::NonisolatedUnsafe) {
2022+
if (state.isUnsafe()) {
20202023
out << "(unsafe)";
20212024
}
20222025
break;

lib/IDE/CompletionLookup.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,8 +827,9 @@ void CompletionLookup::analyzeActorIsolation(
827827
break;
828828
case ActorIsolation::Unspecified:
829829
case ActorIsolation::Nonisolated:
830-
case ActorIsolation::CallerIsolationInheriting:
831830
case ActorIsolation::NonisolatedUnsafe:
831+
case ActorIsolation::Concurrent:
832+
case ActorIsolation::ConcurrentUnsafe:
832833
return;
833834
}
834835
}

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,8 +1651,7 @@ class DestructureInputs {
16511651
// enabled.
16521652
if (TC.Context.LangOpts.hasFeature(
16531653
Feature::NonIsolatedAsyncInheritsIsolationFromContext) &&
1654-
IsolationInfo &&
1655-
IsolationInfo->getKind() == ActorIsolation::CallerIsolationInheriting &&
1654+
IsolationInfo && IsolationInfo->isNonisolated() &&
16561655
extInfoBuilder.isAsync()) {
16571656
auto actorProtocol = TC.Context.getProtocol(KnownProtocolKind::Actor);
16581657
auto actorType =
@@ -2530,15 +2529,15 @@ static CanSILFunctionType getSILFunctionType(
25302529
std::optional<ActorIsolation> actorIsolation;
25312530
if (constant) {
25322531
if (constant->kind == SILDeclRef::Kind::Deallocator) {
2533-
actorIsolation = ActorIsolation::forNonisolated(false);
2532+
actorIsolation = ActorIsolation::forConcurrent(false);
25342533
} else if (auto *decl = constant->getAbstractFunctionDecl();
25352534
decl && decl->getExecutionBehavior().has_value()) {
25362535
switch (*decl->getExecutionBehavior()) {
25372536
case ExecutionKind::Concurrent:
2538-
actorIsolation = ActorIsolation::forNonisolated(false /*unsafe*/);
2537+
actorIsolation = ActorIsolation::forConcurrent(false /*unsafe*/);
25392538
break;
25402539
case ExecutionKind::Caller:
2541-
actorIsolation = ActorIsolation::forCallerIsolationInheriting();
2540+
actorIsolation = ActorIsolation::forNonisolated(false /*unsafe*/);
25422541
break;
25432542
}
25442543
} else {

lib/SILGen/SILGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ static ActorIsolation getActorIsolationForFunction(SILFunction &fn) {
735735
if (constant.kind == SILDeclRef::Kind::Deallocator) {
736736
// Deallocating destructor is always nonisolated. Isolation of the deinit
737737
// applies only to isolated deallocator and destroyer.
738-
return ActorIsolation::forNonisolated(false);
738+
return ActorIsolation::forConcurrent(false);
739739
}
740740

741741
// If we have actor isolation for our constant, put the isolation onto the

lib/SILGen/SILGenApply.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3104,8 +3104,9 @@ static void emitDelayedArguments(SILGenFunction &SGF,
31043104

31053105
case ActorIsolation::Unspecified:
31063106
case ActorIsolation::Nonisolated:
3107-
case ActorIsolation::CallerIsolationInheriting:
31083107
case ActorIsolation::NonisolatedUnsafe:
3108+
case ActorIsolation::Concurrent:
3109+
case ActorIsolation::ConcurrentUnsafe:
31093110
llvm_unreachable("Not isolated");
31103111
}
31113112

@@ -5832,8 +5833,9 @@ RValue SILGenFunction::emitApply(
58325833

58335834
case ActorIsolation::Unspecified:
58345835
case ActorIsolation::Nonisolated:
5835-
case ActorIsolation::CallerIsolationInheriting:
58365836
case ActorIsolation::NonisolatedUnsafe:
5837+
case ActorIsolation::Concurrent:
5838+
case ActorIsolation::ConcurrentUnsafe:
58375839
llvm_unreachable("Not isolated");
58385840
break;
58395841
}

0 commit comments

Comments
 (0)