Skip to content

Commit c26c502

Browse files
committed
[Actor isolation] Compute actor isolation properly even in Swift interfaces.
The check that limited inference of actor isolation meant that we were incorrectly computing actor isolation for (e.g.) overrides when parsing from Swift interfaces. Only limit inference for cases where we are guaranteed to synthesize an attribute by inference.
1 parent 43df1d8 commit c26c502

File tree

2 files changed

+41
-25
lines changed

2 files changed

+41
-25
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2283,10 +2283,6 @@ ActorIsolation ActorIsolationRequest::evaluate(
22832283
defaultIsolation = ActorIsolation::forActorInstance(classDecl);
22842284
}
22852285

2286-
// Disable inference of actor attributes outside of normal Swift source files.
2287-
if (!shouldInferAttributeInContext(value->getDeclContext()))
2288-
return defaultIsolation;
2289-
22902286
// Function used when returning an inferred isolation.
22912287
auto inferredIsolation = [&](ActorIsolation inferred) {
22922288
// Add an implicit attribute to capture the actor isolation that was
@@ -2340,29 +2336,31 @@ ActorIsolation ActorIsolationRequest::evaluate(
23402336
return getActorIsolation(accessor->getStorage());
23412337
}
23422338

2343-
// If the declaration witnesses a protocol requirement that is isolated,
2344-
// use that.
2345-
if (auto witnessedIsolation = getIsolationFromWitnessedRequirements(value)) {
2346-
return inferredIsolation(*witnessedIsolation);
2347-
}
2339+
if (shouldInferAttributeInContext(value->getDeclContext())) {
2340+
// If the declaration witnesses a protocol requirement that is isolated,
2341+
// use that.
2342+
if (auto witnessedIsolation = getIsolationFromWitnessedRequirements(value)) {
2343+
return inferredIsolation(*witnessedIsolation);
2344+
}
2345+
2346+
// If the declaration is a class with a superclass that has specified
2347+
// isolation, use that.
2348+
if (auto classDecl = dyn_cast<ClassDecl>(value)) {
2349+
if (auto superclassDecl = classDecl->getSuperclassDecl()) {
2350+
auto superclassIsolation = getActorIsolation(superclassDecl);
2351+
if (!superclassIsolation.isUnspecified()) {
2352+
if (superclassIsolation.requiresSubstitution()) {
2353+
Type superclassType = classDecl->getSuperclass();
2354+
if (!superclassType)
2355+
return ActorIsolation::forUnspecified();
2356+
2357+
SubstitutionMap subs = superclassType->getMemberSubstitutionMap(
2358+
classDecl->getModuleContext(), classDecl);
2359+
superclassIsolation = superclassIsolation.subst(subs);
2360+
}
23482361

2349-
// If the declaration is a class with a superclass that has specified
2350-
// isolation, use that.
2351-
if (auto classDecl = dyn_cast<ClassDecl>(value)) {
2352-
if (auto superclassDecl = classDecl->getSuperclassDecl()) {
2353-
auto superclassIsolation = getActorIsolation(superclassDecl);
2354-
if (!superclassIsolation.isUnspecified()) {
2355-
if (superclassIsolation.requiresSubstitution()) {
2356-
Type superclassType = classDecl->getSuperclass();
2357-
if (!superclassType)
2358-
return ActorIsolation::forUnspecified();
2359-
2360-
SubstitutionMap subs = superclassType->getMemberSubstitutionMap(
2361-
classDecl->getModuleContext(), classDecl);
2362-
superclassIsolation = superclassIsolation.subst(subs);
2362+
return inferredIsolation(superclassIsolation);
23632363
}
2364-
2365-
return inferredIsolation(superclassIsolation);
23662364
}
23672365
}
23682366
}

test/ModuleInterface/actor_objc.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule -emit-module-interface-path %t/Test.swiftinterface -module-name Test -enable-experimental-concurrency %s
3+
// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix CHECK < %t/Test.swiftinterface
4+
// RUN: %target-swift-frontend -typecheck-module-from-interface -module-name Test %t/Test.swiftinterface
5+
6+
// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-module-interface-path %t/TestFromModule.swiftinterface -module-name Test -enable-experimental-concurrency
7+
// RUN: %FileCheck %s --check-prefix FROMMODULE --check-prefix CHECK < %t/TestFromModule.swiftinterface
8+
// RUN: %target-swift-frontend -typecheck-module-from-interface -module-name Test %t/TestFromModule.swiftinterface
9+
10+
// REQUIRES: concurrency
11+
// REQUIRES: objc_interop
12+
13+
import Foundation
14+
15+
// CHECK-LABEL: @objc @_inheritsConvenienceInitializers public actor SomeActor : ObjectiveC.NSObject {
16+
// CHECK: @objc override dynamic public init()
17+
public actor SomeActor: NSObject {
18+
}

0 commit comments

Comments
 (0)