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