mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
test/ModuleInterface/actor_objc.swift
Normal file
18
test/ModuleInterface/actor_objc.swift
Normal 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 {
|
||||
}
|
||||
Reference in New Issue
Block a user