[Concurrency] SE-0449: Implied conformances to nonisolated protocols make witnesses nonisolated

Even if the requirement is stated on an isolated protocol if the
conformance is implied by a nonisolated one all of the requirements
and witnesses should be nonisolated.

(cherry picked from commit 06be7bda39)
This commit is contained in:
Pavel Yaskevich
2025-06-17 00:05:16 -07:00
parent 6e245641a2
commit 7d0e2b51fd
2 changed files with 39 additions and 0 deletions

View File

@@ -5156,6 +5156,11 @@ getIsolationFromWitnessedRequirements(ValueDecl *value) {
std::tuple<ProtocolConformance *, ActorIsolation, ValueDecl *>;
SmallVector<IsolatedRequirement, 2> isolatedRequirements;
for (auto conformance : conformances) {
auto *implied =
conformance->getSourceKind() == ConformanceEntryKind::Implied
? conformance->getImplyingConformance()
: nullptr;
auto protocol = conformance->getProtocol();
for (auto found : protocol->lookupDirect(value->getName())) {
if (!isa<ProtocolDecl>(found->getDeclContext()))
@@ -5165,6 +5170,19 @@ getIsolationFromWitnessedRequirements(ValueDecl *value) {
if (!requirement || isa<TypeDecl>(requirement))
continue;
// The conformance implied by an explicitly stated nonisolated protocol
// makes all of the requirements nonisolated.
if (implied &&
implied->getSourceKind() == ConformanceEntryKind::Explicit) {
auto protocol = implied->getProtocol();
if (protocol->getAttrs().hasAttribute<NonisolatedAttr>()) {
isolatedRequirements.push_back(IsolatedRequirement{
implied, ActorIsolation::forNonisolated(/*unsafe=*/false),
requirement});
continue;
}
}
auto requirementIsolation = getActorIsolation(requirement);
switch (requirementIsolation) {
case ActorIsolation::ActorInstance: