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.
This commit is contained in:
Michael Gottesman
2025-01-16 10:41:02 -08:00
committed by GitHub
2 changed files with 32 additions and 4 deletions

View File

@@ -5950,10 +5950,19 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
if (auto selfTypeDecl = value->getDeclContext()->getSelfNominalTypeDecl()) {
auto selfTypeIsolation = getInferredActorIsolation(selfTypeDecl);
if (selfTypeIsolation.isolation) {
return {
inferredIsolation(selfTypeIsolation.isolation, onlyGlobal),
selfTypeIsolation.source
};
auto isolation = selfTypeIsolation.isolation;
if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
ctx.LangOpts.hasFeature(
Feature::NonIsolatedAsyncInheritsIsolationFromContext) &&
func && func->hasAsync() &&
func->getModuleContext() == ctx.MainModule &&
isolation.isNonisolated()) {
isolation = ActorIsolation::forCallerIsolationInheriting();
}
return {inferredIsolation(isolation, onlyGlobal),
selfTypeIsolation.source};
}
}
}

View File

@@ -16,6 +16,11 @@
class NonSendableKlass {}
nonisolated class NonIsolatedNonSendableKlass {
func unspecifiedMethod() async {}
nonisolated func nonisolatedMethod() async {}
}
func unspecifiedSyncUse<T>(_ t: T) {}
func unspecifiedAsyncUse<T>(_ t: T) async {}
nonisolated func nonisolatedSyncUse<T>(_ t: T) {}
@@ -148,3 +153,17 @@ class MainActorKlass {
// 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}}
}
}
// We should not error on either of these since c is in the main actor's region
// and our nonisolated/unspecified methods are inheriting the main actor
// isolation which is safe since they are type checked as something that cannot
// access any state that is outside of the current actor that c is reachable from.
@MainActor
func validateNonisolatedOnClassMeansCallerIsolationInheritingOnFuncDecl(
c: NonIsolatedNonSendableKlass
) async {
await c.unspecifiedMethod() // expected-disabled-error {{sending 'c' risks causing data races}}
// 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}}
await c.nonisolatedMethod() // expected-disabled-error {{sending 'c' risks causing data races}}
// 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}}
}