Skip to content

Commit 952d4af

Browse files
Added more tests. Implemented logic for inferring actor isolation for deinit from base class and skipping isolation when deinit is implicit.
1 parent 10ee948 commit 952d4af

File tree

2 files changed

+169
-30
lines changed

2 files changed

+169
-30
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5044,9 +5044,65 @@ ActorIsolation ActorIsolationRequest::evaluate(
50445044
Evaluator &evaluator, ValueDecl *value) const {
50455045
auto &ctx = value->getASTContext();
50465046

5047+
const bool hasIsolatedSelf =
5048+
evaluateOrDefault(evaluator, HasIsolatedSelfRequest{value}, false);
5049+
5050+
auto addAttributesForActorIsolation = [&](ActorIsolation isolation) {
5051+
ASTContext &ctx = value->getASTContext();
5052+
switch (isolation) {
5053+
case ActorIsolation::Nonisolated:
5054+
case ActorIsolation::NonisolatedUnsafe: {
5055+
value->getAttrs().add(new (ctx) NonisolatedAttr(
5056+
isolation == ActorIsolation::NonisolatedUnsafe, /*implicit=*/true));
5057+
break;
5058+
}
5059+
case ActorIsolation::GlobalActor: {
5060+
auto typeExpr = TypeExpr::createImplicit(isolation.getGlobalActor(), ctx);
5061+
auto attr = CustomAttr::create(ctx, SourceLoc(), typeExpr, /*implicit=*/true);
5062+
value->getAttrs().add(attr);
5063+
5064+
if (isolation.preconcurrency() && !value->getAttrs().hasAttribute<PreconcurrencyAttr>()) {
5065+
auto preconcurrency = new (ctx) PreconcurrencyAttr(/*isImplicit*/true);
5066+
value->getAttrs().add(preconcurrency);
5067+
}
5068+
break;
5069+
}
5070+
case ActorIsolation::Erased:
5071+
llvm_unreachable("cannot add attributes for erased isolation");
5072+
case ActorIsolation::ActorInstance: {
5073+
// Nothing to do. Default value for actors.
5074+
assert(hasIsolatedSelf);
5075+
break;
5076+
}
5077+
case ActorIsolation::Unspecified: {
5078+
// Nothing to do. Default value for non-actors.
5079+
assert(!hasIsolatedSelf);
5080+
break;
5081+
}
5082+
}
5083+
};
5084+
5085+
// No need to isolate implicit deinit, unless there is already an isolated one
5086+
// in the superclass
5087+
if (value->isImplicit() && isa<DestructorDecl>(value)) {
5088+
ValueDecl *overriddenValue = value->getOverriddenDeclOrSuperDeinit();
5089+
ActorIsolation isolation = ActorIsolation::forUnspecified();
5090+
if (overriddenValue) {
5091+
isolation = getOverriddenIsolationFor(value);
5092+
} else if (hasIsolatedSelf) {
5093+
// Don't use 'unspecified' for actors, use 'nonisolated' instead
5094+
// To force generation of the 'nonisolated' attribute in SIL and
5095+
// .swiftmodule
5096+
isolation = ActorIsolation::forNonisolated(false);
5097+
}
5098+
5099+
addAttributesForActorIsolation(isolation);
5100+
return isolation;
5101+
}
5102+
50475103
// If this declaration has actor-isolated "self", it's isolated to that
50485104
// actor.
5049-
if (evaluateOrDefault(evaluator, HasIsolatedSelfRequest{value}, false)) {
5105+
if (hasIsolatedSelf) {
50505106
auto actor = value->getDeclContext()->getSelfNominalTypeDecl();
50515107
assert(actor && "could not find the actor that 'self' is isolated to");
50525108

@@ -5190,7 +5246,7 @@ ActorIsolation ActorIsolationRequest::evaluate(
51905246

51915247
// Look for and remember the overridden declaration's isolation.
51925248
std::optional<ActorIsolation> overriddenIso;
5193-
ValueDecl *overriddenValue = value->getOverriddenDecl();
5249+
ValueDecl *overriddenValue = value->getOverriddenDeclOrSuperDeinit();
51945250
if (overriddenValue) {
51955251
// use the overridden decl's iso as the default isolation for this decl.
51965252
defaultIsolation = getOverriddenIsolationFor(value);
@@ -5236,27 +5292,15 @@ ActorIsolation ActorIsolationRequest::evaluate(
52365292
inferred.preconcurrency());
52375293
}
52385294

5239-
value->getAttrs().add(new (ctx) NonisolatedAttr(
5240-
inferred == ActorIsolation::NonisolatedUnsafe, /*implicit=*/true));
5295+
// Add nonisolated attribute
5296+
addAttributesForActorIsolation(inferred);
52415297
break;
52425298

52435299
case ActorIsolation::Erased:
52445300
llvm_unreachable("cannot infer erased isolation");
5245-
52465301
case ActorIsolation::GlobalActor: {
5247-
auto typeExpr =
5248-
TypeExpr::createImplicit(inferred.getGlobalActor(), ctx);
5249-
auto attr =
5250-
CustomAttr::create(ctx, SourceLoc(), typeExpr, /*implicit=*/true);
5251-
value->getAttrs().add(attr);
5252-
5253-
if (inferred.preconcurrency() &&
5254-
!value->getAttrs().hasAttribute<PreconcurrencyAttr>()) {
5255-
auto preconcurrency =
5256-
new (ctx) PreconcurrencyAttr(/*isImplicit*/true);
5257-
value->getAttrs().add(preconcurrency);
5258-
}
5259-
5302+
// Add global actor attribute
5303+
addAttributesForActorIsolation(inferred);
52605304
break;
52615305
}
52625306

0 commit comments

Comments
 (0)