Skip to content

Commit 542f4ee

Browse files
committed
[Sema] Respect global actors on autoclosures
Previously we would only respect global actors set on explicit closure expressions. Respect them on autoclosures too.
1 parent 3232c04 commit 542f4ee

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4458,17 +4458,21 @@ namespace {
44584458
}
44594459

44604460
// Attempt to resolve the global actor type of a closure.
4461-
Type resolveGlobalActorType(ClosureExpr *closure) {
4461+
Type resolveGlobalActorType(AbstractClosureExpr *ACE) {
44624462
// Check whether the closure's type has a global actor already.
4463-
if (Type closureType = getType(closure)) {
4463+
if (Type closureType = getType(ACE)) {
44644464
if (auto closureFnType = closureType->getAs<FunctionType>()) {
44654465
if (Type globalActor = closureFnType->getGlobalActor())
44664466
return globalActor;
44674467
}
44684468
}
44694469

44704470
// Look for an explicit attribute.
4471-
return getExplicitGlobalActor(closure);
4471+
if (auto *CE = dyn_cast<ClosureExpr>(ACE)) {
4472+
if (auto globalActor = getExplicitGlobalActor(CE))
4473+
return globalActor;
4474+
}
4475+
return Type();
44724476
}
44734477

44744478
public:
@@ -4480,14 +4484,16 @@ namespace {
44804484
AbstractClosureExpr *closure) {
44814485
bool preconcurrency = false;
44824486

4483-
if (auto explicitClosure = dyn_cast<ClosureExpr>(closure)) {
4487+
if (auto explicitClosure = dyn_cast<ClosureExpr>(closure))
44844488
preconcurrency = explicitClosure->isIsolatedByPreconcurrency();
44854489

4486-
// If the closure specifies a global actor, use it.
4487-
if (Type globalActor = resolveGlobalActorType(explicitClosure))
4488-
return ActorIsolation::forGlobalActor(globalActor)
4489-
.withPreconcurrency(preconcurrency);
4490+
// If the closure specifies a global actor, use it.
4491+
if (Type globalActor = resolveGlobalActorType(closure)) {
4492+
return ActorIsolation::forGlobalActor(globalActor)
4493+
.withPreconcurrency(preconcurrency);
4494+
}
44904495

4496+
if (auto *explicitClosure = dyn_cast<ClosureExpr>(closure)) {
44914497
if (auto *attr =
44924498
explicitClosure->getAttrs().getAttribute<NonisolatedAttr>();
44934499
attr && ctx.LangOpts.hasFeature(Feature::ClosureIsolation)) {

test/Concurrency/global_actor_function_types.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,3 +413,28 @@ extension GlobalType {
413413
rhs: GlobalType
414414
) -> Bool { true }
415415
}
416+
417+
func takesMainActorFn(_ x: @MainActor () -> Int) {}
418+
func takesMainActorAutoclosure(_ x: @autoclosure @MainActor () -> Int) {}
419+
420+
func nonisolatedIntFn() -> Int { 0 }
421+
@MainActor func mainActorIntFn() -> Int { 0 }
422+
423+
struct HasMainActorFns {
424+
@MainActor static func staticFn() -> Int { 0 }
425+
@MainActor func instanceFn() -> Int { 0 }
426+
}
427+
428+
func testGlobalActorAutoclosure(_ x: HasMainActorFns) {
429+
takesMainActorFn(nonisolatedIntFn)
430+
takesMainActorFn(mainActorIntFn)
431+
432+
// Make sure we respect global actors on autoclosures.
433+
takesMainActorAutoclosure(nonisolatedIntFn())
434+
takesMainActorAutoclosure(mainActorIntFn())
435+
436+
// Including autoclosure thunks.
437+
takesMainActorFn(HasMainActorFns.staticFn)
438+
takesMainActorFn(HasMainActorFns.instanceFn(x))
439+
takesMainActorFn(x.instanceFn)
440+
}

0 commit comments

Comments
 (0)