Skip to content

Commit 2adc68b

Browse files
authored
Merge pull request #78665 from gottesmm/pr-054dfe289af455d0471eefd8e16ff4496a45c2f9
[concurrency] Inherit caller isolation inheriting when inferring isolation from a nominal type context for a method on the nominal type.
2 parents 0e77477 + 2651272 commit 2adc68b

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5950,10 +5950,19 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
59505950
if (auto selfTypeDecl = value->getDeclContext()->getSelfNominalTypeDecl()) {
59515951
auto selfTypeIsolation = getInferredActorIsolation(selfTypeDecl);
59525952
if (selfTypeIsolation.isolation) {
5953-
return {
5954-
inferredIsolation(selfTypeIsolation.isolation, onlyGlobal),
5955-
selfTypeIsolation.source
5956-
};
5953+
auto isolation = selfTypeIsolation.isolation;
5954+
5955+
if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
5956+
ctx.LangOpts.hasFeature(
5957+
Feature::NonIsolatedAsyncInheritsIsolationFromContext) &&
5958+
func && func->hasAsync() &&
5959+
func->getModuleContext() == ctx.MainModule &&
5960+
isolation.isNonisolated()) {
5961+
isolation = ActorIsolation::forCallerIsolationInheriting();
5962+
}
5963+
5964+
return {inferredIsolation(isolation, onlyGlobal),
5965+
selfTypeIsolation.source};
59575966
}
59585967
}
59595968
}

test/Concurrency/nonisolated_inherits_isolation.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616

1717
class NonSendableKlass {}
1818

19+
nonisolated class NonIsolatedNonSendableKlass {
20+
func unspecifiedMethod() async {}
21+
nonisolated func nonisolatedMethod() async {}
22+
}
23+
1924
func unspecifiedSyncUse<T>(_ t: T) {}
2025
func unspecifiedAsyncUse<T>(_ t: T) async {}
2126
nonisolated func nonisolatedSyncUse<T>(_ t: T) {}
@@ -148,3 +153,17 @@ class MainActorKlass {
148153
// expected-enabled-note @-1 {{sending main actor-isolated 'x4' to global actor 'CustomActor'-isolated global function 'sendToCustom' risks causing data races between global actor 'CustomActor'-isolated and main actor-isolated uses}}
149154
}
150155
}
156+
157+
// We should not error on either of these since c is in the main actor's region
158+
// and our nonisolated/unspecified methods are inheriting the main actor
159+
// isolation which is safe since they are type checked as something that cannot
160+
// access any state that is outside of the current actor that c is reachable from.
161+
@MainActor
162+
func validateNonisolatedOnClassMeansCallerIsolationInheritingOnFuncDecl(
163+
c: NonIsolatedNonSendableKlass
164+
) async {
165+
await c.unspecifiedMethod() // expected-disabled-error {{sending 'c' risks causing data races}}
166+
// expected-disabled-note @-1 {{sending main actor-isolated 'c' to nonisolated instance method 'unspecifiedMethod()' risks causing data races between nonisolated and main actor-isolated uses}}
167+
await c.nonisolatedMethod() // expected-disabled-error {{sending 'c' risks causing data races}}
168+
// expected-disabled-note @-1 {{sending main actor-isolated 'c' to nonisolated instance method 'nonisolatedMethod()' risks causing data races between nonisolated and main actor-isolated uses}}
169+
}

0 commit comments

Comments
 (0)