Skip to content

Commit 9f225d6

Browse files
authored
Merge pull request #68567 from hborla/unify-actor-isolation
[Concurrency] Remove `ClosureActorIsolation`.
2 parents 94c2be8 + 549b452 commit 9f225d6

File tree

13 files changed

+122
-194
lines changed

13 files changed

+122
-194
lines changed

include/swift/AST/ActorIsolation.h

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,6 @@ class NominalTypeDecl;
3131
class SubstitutionMap;
3232
class AbstractFunctionDecl;
3333
class AbstractClosureExpr;
34-
class ClosureActorIsolation;
35-
36-
/// Trampoline for AbstractClosureExpr::getActorIsolation.
37-
ClosureActorIsolation
38-
__AbstractClosureExpr_getActorIsolation(AbstractClosureExpr *CE);
39-
40-
/// Returns a function reference to \c __AbstractClosureExpr_getActorIsolation.
41-
/// This is needed so we can use it as a default argument for
42-
/// \c getActorIsolationOfContext without knowing the layout of
43-
/// \c ClosureActorIsolation.
44-
llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
45-
_getRef__AbstractClosureExpr_getActorIsolation();
4634

4735
/// Determine whether the given types are (canonically) equal, declared here
4836
/// to avoid having to include Types.h.
@@ -83,23 +71,28 @@ class ActorIsolation {
8371

8472
private:
8573
union {
86-
NominalTypeDecl *actor;
74+
llvm::PointerUnion<NominalTypeDecl *, VarDecl *> actorInstance;
8775
Type globalActor;
8876
void *pointer;
8977
};
9078
unsigned kind : 3;
9179
unsigned isolatedByPreconcurrency : 1;
9280
unsigned parameterIndex : 28;
9381

94-
ActorIsolation(Kind kind, NominalTypeDecl *actor, unsigned parameterIndex)
95-
: actor(actor), kind(kind), isolatedByPreconcurrency(false),
96-
parameterIndex(parameterIndex) { }
82+
ActorIsolation(Kind kind, NominalTypeDecl *actor, unsigned parameterIndex);
83+
84+
ActorIsolation(Kind kind, VarDecl *capturedActor);
9785

9886
ActorIsolation(Kind kind, Type globalActor)
9987
: globalActor(globalActor), kind(kind), isolatedByPreconcurrency(false),
10088
parameterIndex(0) { }
10189

10290
public:
91+
// No-argument constructor needed for DenseMap use in PostfixCompletion.cpp
92+
explicit ActorIsolation(Kind kind = Unspecified)
93+
: pointer(nullptr), kind(kind), isolatedByPreconcurrency(false),
94+
parameterIndex(0) { }
95+
10396
static ActorIsolation forUnspecified() {
10497
return ActorIsolation(Unspecified, nullptr);
10598
}
@@ -117,6 +110,10 @@ class ActorIsolation {
117110
return ActorIsolation(ActorInstance, actor, parameterIndex + 1);
118111
}
119112

113+
static ActorIsolation forActorInstanceCapture(VarDecl *capturedActor) {
114+
return ActorIsolation(ActorInstance, capturedActor);
115+
}
116+
120117
static ActorIsolation forGlobalActor(Type globalActor, bool unsafe) {
121118
return ActorIsolation(
122119
unsafe ? GlobalActorUnsafe : GlobalActor, globalActor);
@@ -151,10 +148,9 @@ class ActorIsolation {
151148
}
152149
}
153150

154-
NominalTypeDecl *getActor() const {
155-
assert(getKind() == ActorInstance);
156-
return actor;
157-
}
151+
NominalTypeDecl *getActor() const;
152+
153+
VarDecl *getActorInstance() const;
158154

159155
bool isGlobalActor() const {
160156
return getKind() == GlobalActor || getKind() == GlobalActorUnsafe;
@@ -200,7 +196,8 @@ class ActorIsolation {
200196
return true;
201197

202198
case ActorInstance:
203-
return lhs.actor == rhs.actor && lhs.parameterIndex == rhs.parameterIndex;
199+
return (lhs.getActor() == rhs.getActor() &&
200+
lhs.parameterIndex == rhs.parameterIndex);
204201

205202
case GlobalActor:
206203
case GlobalActorUnsafe:
@@ -223,16 +220,19 @@ class ActorIsolation {
223220
/// Determine how the given value declaration is isolated.
224221
ActorIsolation getActorIsolation(ValueDecl *value);
225222

223+
/// Trampoline for AbstractClosureExpr::getActorIsolation.
224+
ActorIsolation
225+
__AbstractClosureExpr_getActorIsolation(AbstractClosureExpr *CE);
226+
226227
/// Determine how the given declaration context is isolated.
227228
/// \p getClosureActorIsolation allows the specification of actor isolation for
228229
/// closures that haven't been saved been saved to the AST yet. This is useful
229230
/// for solver-based code completion which doesn't modify the AST but stores the
230231
/// actor isolation of closures in the constraint system solution.
231232
ActorIsolation getActorIsolationOfContext(
232233
DeclContext *dc,
233-
llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
234-
getClosureActorIsolation =
235-
_getRef__AbstractClosureExpr_getActorIsolation());
234+
llvm::function_ref<ActorIsolation(AbstractClosureExpr *)>
235+
getClosureActorIsolation = __AbstractClosureExpr_getActorIsolation);
236236

237237
/// Check if both the value, and context are isolated to the same actor.
238238
bool isSameActorIsolated(ValueDecl *value, DeclContext *dc);
@@ -256,9 +256,9 @@ bool usesFlowSensitiveIsolation(AbstractFunctionDecl const *fn);
256256
/// \return true if it is safe to drop the global-actor qualifier.
257257
bool safeToDropGlobalActor(
258258
DeclContext *dc, Type globalActor, Type ty,
259-
llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
259+
llvm::function_ref<ActorIsolation(AbstractClosureExpr *)>
260260
getClosureActorIsolation =
261-
_getRef__AbstractClosureExpr_getActorIsolation());
261+
__AbstractClosureExpr_getActorIsolation);
262262

263263
void simple_display(llvm::raw_ostream &out, const ActorIsolation &state);
264264

include/swift/AST/Expr.h

Lines changed: 7 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -3777,92 +3777,6 @@ class SequenceExpr final : public Expr,
37773777
}
37783778
};
37793779

3780-
/// Actor isolation for a closure.
3781-
class ClosureActorIsolation {
3782-
public:
3783-
enum Kind {
3784-
/// The closure is not isolated to any actor.
3785-
Nonisolated,
3786-
3787-
/// The closure is tied to the actor instance described by the given
3788-
/// \c VarDecl*, which is the (captured) `self` of an actor.
3789-
ActorInstance,
3790-
3791-
/// The closure is tied to the global actor described by the given type.
3792-
GlobalActor,
3793-
};
3794-
3795-
private:
3796-
/// The actor to which this closure is isolated, plus a bit indicating
3797-
/// whether the isolation was imposed by a preconcurrency declaration.
3798-
///
3799-
/// There are three possible states for the pointer:
3800-
/// - NULL: The closure is independent of any actor.
3801-
/// - VarDecl*: The 'self' variable for the actor instance to which
3802-
/// this closure is isolated. It will always have a type that conforms
3803-
/// to the \c Actor protocol.
3804-
/// - Type: The type of the global actor on which
3805-
llvm::PointerIntPair<llvm::PointerUnion<VarDecl *, Type>, 1, bool> storage;
3806-
3807-
ClosureActorIsolation(VarDecl *selfDecl, bool preconcurrency)
3808-
: storage(selfDecl, preconcurrency) { }
3809-
ClosureActorIsolation(Type globalActorType, bool preconcurrency)
3810-
: storage(globalActorType, preconcurrency) { }
3811-
3812-
public:
3813-
ClosureActorIsolation(bool preconcurrency = false)
3814-
: storage(nullptr, preconcurrency) { }
3815-
3816-
static ClosureActorIsolation forNonisolated(bool preconcurrency) {
3817-
return ClosureActorIsolation(preconcurrency);
3818-
}
3819-
3820-
static ClosureActorIsolation forActorInstance(VarDecl *selfDecl,
3821-
bool preconcurrency) {
3822-
return ClosureActorIsolation(selfDecl, preconcurrency);
3823-
}
3824-
3825-
static ClosureActorIsolation forGlobalActor(Type globalActorType,
3826-
bool preconcurrency) {
3827-
return ClosureActorIsolation(globalActorType, preconcurrency);
3828-
}
3829-
3830-
/// Determine the kind of isolation.
3831-
Kind getKind() const {
3832-
if (storage.getPointer().isNull())
3833-
return Kind::Nonisolated;
3834-
3835-
if (storage.getPointer().is<VarDecl *>())
3836-
return Kind::ActorInstance;
3837-
3838-
return Kind::GlobalActor;
3839-
}
3840-
3841-
/// Whether the closure is isolated at all.
3842-
explicit operator bool() const {
3843-
return getKind() != Kind::Nonisolated;
3844-
}
3845-
3846-
/// Whether the closure is isolated at all.
3847-
operator Kind() const {
3848-
return getKind();
3849-
}
3850-
3851-
VarDecl *getActorInstance() const {
3852-
return storage.getPointer().dyn_cast<VarDecl *>();
3853-
}
3854-
3855-
Type getGlobalActor() const {
3856-
return storage.getPointer().dyn_cast<Type>();
3857-
}
3858-
3859-
bool preconcurrency() const {
3860-
return storage.getInt();
3861-
}
3862-
3863-
ActorIsolation getActorIsolation() const;
3864-
};
3865-
38663780
/// A base class for closure expressions.
38673781
class AbstractClosureExpr : public DeclContext, public Expr {
38683782
CaptureInfo Captures;
@@ -3871,14 +3785,15 @@ class AbstractClosureExpr : public DeclContext, public Expr {
38713785
ParameterList *parameterList;
38723786

38733787
/// Actor isolation of the closure.
3874-
ClosureActorIsolation actorIsolation;
3788+
ActorIsolation actorIsolation;
38753789

38763790
public:
38773791
AbstractClosureExpr(ExprKind Kind, Type FnType, bool Implicit,
38783792
DeclContext *Parent)
38793793
: DeclContext(DeclContextKind::AbstractClosureExpr, Parent),
38803794
Expr(Kind, Implicit, FnType),
3881-
parameterList(nullptr) {
3795+
parameterList(nullptr),
3796+
actorIsolation(ActorIsolation::forUnspecified()) {
38823797
Bits.AbstractClosureExpr.Discriminator = InvalidDiscriminator;
38833798
}
38843799

@@ -3951,9 +3866,11 @@ class AbstractClosureExpr : public DeclContext, public Expr {
39513866
/// returns nullptr if the closure doesn't have a body
39523867
BraceStmt *getBody() const;
39533868

3954-
ClosureActorIsolation getActorIsolation() const { return actorIsolation; }
3869+
ActorIsolation getActorIsolation() const {
3870+
return actorIsolation;
3871+
}
39553872

3956-
void setActorIsolation(ClosureActorIsolation actorIsolation) {
3873+
void setActorIsolation(ActorIsolation actorIsolation) {
39573874
this->actorIsolation = actorIsolation;
39583875
}
39593876

include/swift/IDE/CompletionLookup.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
131131
bool CanCurrDeclContextHandleAsync = false;
132132
/// Actor isolations that were determined during constraint solving but that
133133
/// haven't been saved to the AST.
134-
llvm::DenseMap<AbstractClosureExpr *, ClosureActorIsolation>
134+
llvm::DenseMap<AbstractClosureExpr *, ActorIsolation>
135135
ClosureActorIsolations;
136136
bool HaveDot = false;
137137
bool IsUnwrappedOptional = false;
@@ -253,7 +253,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
253253
}
254254

255255
void setClosureActorIsolations(
256-
llvm::DenseMap<AbstractClosureExpr *, ClosureActorIsolation>
256+
llvm::DenseMap<AbstractClosureExpr *, ActorIsolation>
257257
ClosureActorIsolations) {
258258
this->ClosureActorIsolations = ClosureActorIsolations;
259259
}

include/swift/IDE/PostfixCompletion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class PostfixCompletionCallback : public TypeCheckCompletionCallback {
6363

6464
/// Actor isolations that were determined during constraint solving but that
6565
/// haven't been saved to the AST.
66-
llvm::DenseMap<AbstractClosureExpr *, ClosureActorIsolation>
66+
llvm::DenseMap<AbstractClosureExpr *, ActorIsolation>
6767
ClosureActorIsolations;
6868

6969
/// Checks whether this result has the same \c BaseTy and \c BaseDecl as

include/swift/Sema/IDETypeChecking.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,9 @@ namespace swift {
318318
bool completionContextUsesConcurrencyFeatures(const DeclContext *dc);
319319

320320
/// Determine the isolation of a particular closure.
321-
ClosureActorIsolation determineClosureActorIsolation(
321+
ActorIsolation determineClosureActorIsolation(
322322
AbstractClosureExpr *closure, llvm::function_ref<Type(Expr *)> getType,
323-
llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
323+
llvm::function_ref<ActorIsolation(AbstractClosureExpr *)>
324324
getClosureActorIsolation);
325325

326326
/// If the capture list shadows any declarations using shorthand syntax, i.e.

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2688,15 +2688,17 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, StringRef>,
26882688
printField(E->getRawDiscriminator(), "discriminator", DiscriminatorColor);
26892689

26902690
switch (auto isolation = E->getActorIsolation()) {
2691-
case ClosureActorIsolation::Nonisolated:
2691+
case ActorIsolation::Unspecified:
2692+
case ActorIsolation::Nonisolated:
26922693
break;
26932694

2694-
case ClosureActorIsolation::ActorInstance:
2695+
case ActorIsolation::ActorInstance:
26952696
printFieldQuoted(isolation.getActorInstance()->printRef(),
26962697
"actor_isolated", CapturesColor);
26972698
break;
26982699

2699-
case ClosureActorIsolation::GlobalActor:
2700+
case ActorIsolation::GlobalActor:
2701+
case ActorIsolation::GlobalActorUnsafe:
27002702
printFieldQuoted(isolation.getGlobalActor().getString(),
27012703
"global_actor_isolated", CapturesColor);
27022704
break;

lib/AST/Decl.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10306,11 +10306,13 @@ bool VarDecl::isSelfParamCaptureIsolated() const {
1030610306

1030710307
if (auto closure = dyn_cast<AbstractClosureExpr>(dc)) {
1030810308
switch (auto isolation = closure->getActorIsolation()) {
10309-
case ClosureActorIsolation::Nonisolated:
10310-
case ClosureActorIsolation::GlobalActor:
10309+
case ActorIsolation::Unspecified:
10310+
case ActorIsolation::Nonisolated:
10311+
case ActorIsolation::GlobalActor:
10312+
case ActorIsolation::GlobalActorUnsafe:
1031110313
return false;
1031210314

10313-
case ClosureActorIsolation::ActorInstance:
10315+
case ActorIsolation::ActorInstance:
1031410316
auto isolatedVar = isolation.getActorInstance();
1031510317
return isolatedVar->isSelfParameter() ||
1031610318
isolatedVar-isSelfParamCapture();
@@ -10333,7 +10335,7 @@ ActorIsolation swift::getActorIsolation(ValueDecl *value) {
1033310335

1033410336
ActorIsolation swift::getActorIsolationOfContext(
1033510337
DeclContext *dc,
10336-
llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
10338+
llvm::function_ref<ActorIsolation(AbstractClosureExpr *)>
1033710339
getClosureActorIsolation) {
1033810340
auto dcToUse = dc;
1033910341
// Defer bodies share actor isolation of their enclosing context.
@@ -10349,7 +10351,7 @@ ActorIsolation swift::getActorIsolationOfContext(
1034910351
return getActorIsolation(var);
1035010352

1035110353
if (auto *closure = dyn_cast<AbstractClosureExpr>(dcToUse)) {
10352-
return getClosureActorIsolation(closure).getActorIsolation();
10354+
return getClosureActorIsolation(closure);
1035310355
}
1035410356

1035510357
if (auto *tld = dyn_cast<TopLevelCodeDecl>(dcToUse)) {
@@ -10597,6 +10599,33 @@ void swift::simple_display(llvm::raw_ostream &out, AnyFunctionRef fn) {
1059710599
out << "closure";
1059810600
}
1059910601

10602+
ActorIsolation::ActorIsolation(Kind kind, NominalTypeDecl *actor,
10603+
unsigned parameterIndex)
10604+
: actorInstance(actor), kind(kind),
10605+
isolatedByPreconcurrency(false),
10606+
parameterIndex(parameterIndex) { }
10607+
10608+
ActorIsolation::ActorIsolation(Kind kind, VarDecl *capturedActor)
10609+
: actorInstance(capturedActor), kind(kind),
10610+
isolatedByPreconcurrency(false),
10611+
parameterIndex(0) { }
10612+
10613+
NominalTypeDecl *ActorIsolation::getActor() const {
10614+
assert(getKind() == ActorInstance);
10615+
10616+
if (auto *instance = actorInstance.dyn_cast<VarDecl *>()) {
10617+
return instance->getTypeInContext()
10618+
->getReferenceStorageReferent()->getAnyActor();
10619+
}
10620+
10621+
return actorInstance.get<NominalTypeDecl *>();
10622+
}
10623+
10624+
VarDecl *ActorIsolation::getActorInstance() const {
10625+
assert(getKind() == ActorInstance);
10626+
return actorInstance.dyn_cast<VarDecl *>();
10627+
}
10628+
1060010629
bool ActorIsolation::isMainActor() const {
1060110630
if (isGlobalActor()) {
1060210631
if (auto *nominal = getGlobalActor()->getAnyNominal())

0 commit comments

Comments
 (0)