Skip to content

Commit 06be7bd

Browse files
committed
[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.
1 parent 82497af commit 06be7bd

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5138,6 +5138,11 @@ getIsolationFromWitnessedRequirements(ValueDecl *value) {
51385138
std::tuple<ProtocolConformance *, ActorIsolation, ValueDecl *>;
51395139
SmallVector<IsolatedRequirement, 2> isolatedRequirements;
51405140
for (auto conformance : conformances) {
5141+
auto *implied =
5142+
conformance->getSourceKind() == ConformanceEntryKind::Implied
5143+
? conformance->getImplyingConformance()
5144+
: nullptr;
5145+
51415146
auto protocol = conformance->getProtocol();
51425147
for (auto found : protocol->lookupDirect(value->getName())) {
51435148
if (!isa<ProtocolDecl>(found->getDeclContext()))
@@ -5147,6 +5152,19 @@ getIsolationFromWitnessedRequirements(ValueDecl *value) {
51475152
if (!requirement || isa<TypeDecl>(requirement))
51485153
continue;
51495154

5155+
// The conformance implied by an explicitly stated nonisolated protocol
5156+
// makes all of the requirements nonisolated.
5157+
if (implied &&
5158+
implied->getSourceKind() == ConformanceEntryKind::Explicit) {
5159+
auto protocol = implied->getProtocol();
5160+
if (protocol->getAttrs().hasAttribute<NonisolatedAttr>()) {
5161+
isolatedRequirements.push_back(IsolatedRequirement{
5162+
implied, ActorIsolation::forNonisolated(/*unsafe=*/false),
5163+
requirement});
5164+
continue;
5165+
}
5166+
}
5167+
51505168
auto requirementIsolation = getActorIsolation(requirement);
51515169
switch (requirementIsolation) {
51525170
case ActorIsolation::ActorInstance:

test/Concurrency/nonisolated_rules.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,27 @@ struct TestIsolated : NonisolatedWithMembers {
183183
}
184184
}
185185

186+
@MainActor
187+
protocol Root {
188+
func testRoot()
189+
}
190+
191+
nonisolated protocol Child : Root {
192+
func testChild()
193+
}
194+
195+
struct TestDifferentLevels : Child {
196+
func testRoot() {}
197+
func testChild() {}
198+
func testNonWitness() {}
199+
}
200+
201+
nonisolated func testRequirementsOnMultipleNestingLevels(t: TestDifferentLevels) {
202+
t.testRoot() // okay
203+
t.testChild() // okay
204+
t.testNonWitness() // okay
205+
}
206+
186207
// MARK: - Extensions
187208

188209
nonisolated extension GloballyIsolated {

0 commit comments

Comments
 (0)