mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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:
@@ -5950,10 +5950,19 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
|
|||||||
if (auto selfTypeDecl = value->getDeclContext()->getSelfNominalTypeDecl()) {
|
if (auto selfTypeDecl = value->getDeclContext()->getSelfNominalTypeDecl()) {
|
||||||
auto selfTypeIsolation = getInferredActorIsolation(selfTypeDecl);
|
auto selfTypeIsolation = getInferredActorIsolation(selfTypeDecl);
|
||||||
if (selfTypeIsolation.isolation) {
|
if (selfTypeIsolation.isolation) {
|
||||||
return {
|
auto isolation = selfTypeIsolation.isolation;
|
||||||
inferredIsolation(selfTypeIsolation.isolation, onlyGlobal),
|
|
||||||
selfTypeIsolation.source
|
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};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,11 @@
|
|||||||
|
|
||||||
class NonSendableKlass {}
|
class NonSendableKlass {}
|
||||||
|
|
||||||
|
nonisolated class NonIsolatedNonSendableKlass {
|
||||||
|
func unspecifiedMethod() async {}
|
||||||
|
nonisolated func nonisolatedMethod() async {}
|
||||||
|
}
|
||||||
|
|
||||||
func unspecifiedSyncUse<T>(_ t: T) {}
|
func unspecifiedSyncUse<T>(_ t: T) {}
|
||||||
func unspecifiedAsyncUse<T>(_ t: T) async {}
|
func unspecifiedAsyncUse<T>(_ t: T) async {}
|
||||||
nonisolated func nonisolatedSyncUse<T>(_ t: T) {}
|
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}}
|
// 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}}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user