[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.
This commit is contained in:
Doug Gregor
2021-02-10 15:55:51 -08:00
parent 43df1d8363
commit c26c5029a5
2 changed files with 40 additions and 24 deletions

View File

@@ -2283,10 +2283,6 @@ ActorIsolation ActorIsolationRequest::evaluate(
defaultIsolation = ActorIsolation::forActorInstance(classDecl);
}
// Disable inference of actor attributes outside of normal Swift source files.
if (!shouldInferAttributeInContext(value->getDeclContext()))
return defaultIsolation;
// Function used when returning an inferred isolation.
auto inferredIsolation = [&](ActorIsolation inferred) {
// Add an implicit attribute to capture the actor isolation that was
@@ -2340,29 +2336,31 @@ ActorIsolation ActorIsolationRequest::evaluate(
return getActorIsolation(accessor->getStorage());
}
// If the declaration witnesses a protocol requirement that is isolated,
// use that.
if (auto witnessedIsolation = getIsolationFromWitnessedRequirements(value)) {
return inferredIsolation(*witnessedIsolation);
}
if (shouldInferAttributeInContext(value->getDeclContext())) {
// If the declaration witnesses a protocol requirement that is isolated,
// use that.
if (auto witnessedIsolation = getIsolationFromWitnessedRequirements(value)) {
return inferredIsolation(*witnessedIsolation);
}
// If the declaration is a class with a superclass that has specified
// isolation, use that.
if (auto classDecl = dyn_cast<ClassDecl>(value)) {
if (auto superclassDecl = classDecl->getSuperclassDecl()) {
auto superclassIsolation = getActorIsolation(superclassDecl);
if (!superclassIsolation.isUnspecified()) {
if (superclassIsolation.requiresSubstitution()) {
Type superclassType = classDecl->getSuperclass();
if (!superclassType)
return ActorIsolation::forUnspecified();
// If the declaration is a class with a superclass that has specified
// isolation, use that.
if (auto classDecl = dyn_cast<ClassDecl>(value)) {
if (auto superclassDecl = classDecl->getSuperclassDecl()) {
auto superclassIsolation = getActorIsolation(superclassDecl);
if (!superclassIsolation.isUnspecified()) {
if (superclassIsolation.requiresSubstitution()) {
Type superclassType = classDecl->getSuperclass();
if (!superclassType)
return ActorIsolation::forUnspecified();
SubstitutionMap subs = superclassType->getMemberSubstitutionMap(
classDecl->getModuleContext(), classDecl);
superclassIsolation = superclassIsolation.subst(subs);
SubstitutionMap subs = superclassType->getMemberSubstitutionMap(
classDecl->getModuleContext(), classDecl);
superclassIsolation = superclassIsolation.subst(subs);
}
return inferredIsolation(superclassIsolation);
}
return inferredIsolation(superclassIsolation);
}
}
}

View File

@@ -0,0 +1,18 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule -emit-module-interface-path %t/Test.swiftinterface -module-name Test -enable-experimental-concurrency %s
// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix CHECK < %t/Test.swiftinterface
// RUN: %target-swift-frontend -typecheck-module-from-interface -module-name Test %t/Test.swiftinterface
// 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
// RUN: %FileCheck %s --check-prefix FROMMODULE --check-prefix CHECK < %t/TestFromModule.swiftinterface
// RUN: %target-swift-frontend -typecheck-module-from-interface -module-name Test %t/TestFromModule.swiftinterface
// REQUIRES: concurrency
// REQUIRES: objc_interop
import Foundation
// CHECK-LABEL: @objc @_inheritsConvenienceInitializers public actor SomeActor : ObjectiveC.NSObject {
// CHECK: @objc override dynamic public init()
public actor SomeActor: NSObject {
}