[SE-0470] Enable isolated conformances by default

The IsolatedConformances feature moves to a normal, supported feature.
Remove all of the experimental-feature flags on test cases and such.

The InferIsolatedConformances feature moves to an upcoming feature for
Swift 7. This should become an adoptable feature, adding "nonisolated"
where needed.

(cherry picked from commit 3380331e7e)
This commit is contained in:
Doug Gregor
2025-04-09 16:06:14 -07:00
parent 69758f6213
commit 5e29333d6b
19 changed files with 70 additions and 68 deletions

View File

@@ -32,6 +32,34 @@
strategy, given that the code would eventually become ambiguous anyways when
the deployment target is raised.
* [SE-0470][]:
A protocol conformance can be isolated to a specific global actor, meaning that the conformance can only be used by code running on that actor. Isolated conformances are expressed by specifying the global actor on the conformance itself:
```swift
protocol P {
func f()
}
@MainActor
class MyType: @MainActor P {
/*@MainActor*/ func f() {
// must be called on the main actor
}
}
```
Swift will produce diagnostics if the conformance is directly accessed in code that isn't guaranteed to execute in the same global actor. For example:
```swift
func acceptP<T: P>(_ value: T) { }
/*nonisolated*/ func useIsolatedConformance(myType: MyType) {
acceptP(myType) // error: main actor-isolated conformance of 'MyType' to 'P' cannot be used in nonisolated context
}
```
To address such issues, only use an isolated conformance from code that executes on the same global actor.
* [SE-0419][]:
Introduced the new `Runtime` module, which contains a public API that can
generate backtraces, presently supported on macOS and Linux. Capturing a
@@ -10759,6 +10787,7 @@ using the `.dynamicType` member to retrieve the type of an expression should mig
[SE-0442]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0442-allow-taskgroup-childtaskresult-type-to-be-inferred.md
[SE-0444]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md
[SE-0458]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0458-strict-memory-safety.md
[SE-0470]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0470-isolated-conformances.md
[#64927]: <https://github.com/apple/swift/issues/64927>
[#42697]: <https://github.com/apple/swift/issues/42697>
[#42728]: <https://github.com/apple/swift/issues/42728>

View File

@@ -8486,10 +8486,6 @@ ERROR(attr_abi_failable_mismatch,none,
//===----------------------------------------------------------------------===//
// MARK: Isolated conformances
//===----------------------------------------------------------------------===//
GROUPED_ERROR(isolated_conformance_experimental_feature,IsolatedConformances,
none,
"isolated conformances require experimental feature "
" 'IsolatedConformances'", ())
NOTE(note_isolate_conformance_to_global_actor,none,
"isolate this conformance to the %select{global actor %0|main actor}1 "
"with '@%2'", (Type, bool, StringRef))

View File

@@ -254,6 +254,7 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(MemorySafetyAttributes, 458, "@unsafe attribute")
LANGUAGE_FEATURE(ValueGenerics, 452, "Value generics feature (integer generics)")
LANGUAGE_FEATURE(RawIdentifiers, 451, "Raw identifiers")
LANGUAGE_FEATURE(SendableCompletionHandlers, 463, "Objective-C completion handler parameters are imported as @Sendable")
LANGUAGE_FEATURE(IsolatedConformances, 407, "Global-actor isolated conformances")
// Swift 6
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
@@ -276,6 +277,7 @@ UPCOMING_FEATURE(GlobalActorIsolatedTypesUsability, 0434, 6)
ADOPTABLE_UPCOMING_FEATURE(ExistentialAny, 335, 7)
UPCOMING_FEATURE(InternalImportsByDefault, 409, 7)
UPCOMING_FEATURE(MemberImportVisibility, 444, 7)
UPCOMING_FEATURE(InferIsolatedConformances, 470, 7)
// Optional language features / modes
@@ -495,6 +497,7 @@ ADOPTABLE_EXPERIMENTAL_FEATURE(AsyncCallerExecution, false)
/// Allow custom availability domains to be defined and referenced.
EXPERIMENTAL_FEATURE(CustomAvailability, true)
<<<<<<< HEAD
/// Allow public enumerations to be extensible by default
/// regardless of whether the module they are declared in
/// is resilient or not.
@@ -506,6 +509,8 @@ EXPERIMENTAL_FEATURE(IsolatedConformances, true)
/// Infer conformance isolation on global-actor-conforming types.
EXPERIMENTAL_FEATURE(InferIsolatedConformances, true)
=======
>>>>>>> 3380331e7eb ([SE-0470] Enable isolated conformances by default)
/// Allow SwiftSettings
EXPERIMENTAL_FEATURE(SwiftSettings, false)

View File

@@ -386,11 +386,10 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
// All metatypes are Copyable, Escapable, and BitwiseCopyable.
if (auto kp = protocol->getKnownProtocolKind()) {
switch (*kp) {
case KnownProtocolKind::Sendable:
case KnownProtocolKind::Sendable: {
// Metatypes are generally Sendable, but with isolated conformances we
// cannot assume that metatypes based on type parameters are Sendable.
// Therefore, check for conformance to SendableMetatype.
if (ctx.LangOpts.hasFeature(Feature::IsolatedConformances)) {
auto sendableMetatypeProto =
ctx.getProtocol(KnownProtocolKind::SendableMetatype);
if (sendableMetatypeProto) {
@@ -409,10 +408,8 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
instanceConformance.hasMissingConformance())
break;
}
// Every other metatype is Sendable.
}
LLVM_FALLTHROUGH;
}
case KnownProtocolKind::Copyable:
case KnownProtocolKind::Escapable:

View File

@@ -163,9 +163,7 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(
Diag<> MessageID, ParseTypeReason reason) {
ParserResult<TypeRepr> ty;
if (isParameterSpecifier() &&
!(!Context.LangOpts.hasFeature(Feature::IsolatedConformances) &&
Tok.isContextualKeyword("isolated"))) {
if (isParameterSpecifier()) {
// Type specifier should already be parsed before here. This only happens
// for construct like 'P1 & inout P2'.
diagnose(Tok.getLoc(), diag::attr_only_on_parameters, Tok.getRawText());

View File

@@ -3021,10 +3021,9 @@ namespace {
// FIXME: When passing to a sending parameter, should this be handled
// by region isolation? Or should it always be handled by region
// isolation?
if (ctx.LangOpts.hasFeature(Feature::IsolatedConformances) &&
(mayExecuteConcurrentlyWith(
if (mayExecuteConcurrentlyWith(
localFunc.getAsDeclContext(), getDeclContext()) ||
(explicitClosure && explicitClosure->isPassedToSendingParameter()))) {
(explicitClosure && explicitClosure->isPassedToSendingParameter())) {
GenericSignature genericSig;
if (auto afd = localFunc.getAbstractFunctionDecl())
genericSig = afd->getGenericSignature();
@@ -7931,8 +7930,6 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
auto dc = rootNormal->getDeclContext();
ASTContext &ctx = dc->getASTContext();
if (!ctx.LangOpts.hasFeature(Feature::IsolatedConformances))
return ActorIsolation::forNonisolated(false);
// If the protocol itself is isolated, don't infer isolation for the
// conformance.

View File

@@ -2567,13 +2567,6 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
ComplainLoc, diag::unchecked_conformance_not_special, ProtoType);
}
// Complain if the global-actor-isolated conformances are not enabled.
if (conformance->isIsolated() &&
!Context.LangOpts.hasFeature(Feature::IsolatedConformances)) {
Context.Diags.diagnose(
ComplainLoc, diag::isolated_conformance_experimental_feature);
}
bool allowImpliedConditionalConformance = false;
if (Proto->isSpecificProtocol(KnownProtocolKind::Sendable)) {
// In -swift-version 5 mode, a conditional conformance to a protocol can imply
@@ -4978,8 +4971,7 @@ static void diagnoseConformanceIsolationErrors(
}
// Suggest isolating the conformance, if possible.
if (ctx.LangOpts.hasFeature(Feature::IsolatedConformances) &&
potentialIsolation && potentialIsolation->isGlobalActor() &&
if (potentialIsolation && potentialIsolation->isGlobalActor() &&
!conformance->isIsolated()) {
bool isMainActor = false;
Type globalActorIsolation = potentialIsolation->getGlobalActor();

View File

@@ -1,9 +1,8 @@
// RUN: %target-run-simple-swift(-enable-experimental-feature IsolatedConformances -target %target-swift-5.1-abi-triple) | %FileCheck %s
// RUN: %target-run-simple-swift(-target %target-swift-5.1-abi-triple) | %FileCheck %s
// REQUIRES: executable_test
// REQUIRES: concurrency
// REQUIRES: concurrency_runtime
// REQUIRES: swift_feature_IsolatedConformances
// UNSUPPORTED: back_deployment_runtime
// FIXME: WebAssembly doesn't currently have a good way to install the

View File

@@ -1,6 +1,5 @@
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 5 -strict-concurrency=complete -enable-experimental-feature IsolatedConformances %s
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 5 -strict-concurrency=complete %s
// REQUIRES: swift_feature_IsolatedConformances
// REQUIRES: concurrency
protocol P {

View File

@@ -1,6 +1,5 @@
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -enable-experimental-feature IsolatedConformances -default-isolation MainActor %s
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -default-isolation MainActor %s
// REQUIRES: swift_feature_IsolatedConformances
// REQUIRES: concurrency
nonisolated

View File

@@ -1,7 +1,5 @@
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -enable-experimental-feature IsolatedConformances -enable-experimental-feature InferIsolatedConformances %s
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -enable-upcoming-feature InferIsolatedConformances %s
// REQUIRES: swift_feature_IsolatedConformances
// REQUIRES: swift_feature_InferIsolatedConformances
// REQUIRES: concurrency
protocol P {

View File

@@ -1,7 +1,6 @@
// RUN: %target-typecheck-verify-swift -swift-version 6 -enable-experimental-feature IsolatedConformances -emit-sil -o /dev/null
// RUN: %target-typecheck-verify-swift -swift-version 6 -emit-sil -o /dev/null
// REQUIRES: concurrency
// REQUIRES: swift_feature_IsolatedConformances
protocol Q {

View File

@@ -1,7 +1,6 @@
// RUN: %target-typecheck-verify-swift -swift-version 6 -enable-experimental-feature IsolatedConformances
// RUN: %target-typecheck-verify-swift -swift-version 6
// REQUIRES: concurrency
// REQUIRES: swift_feature_IsolatedConformances
// This test checks for typecheck-only diagnostics involving non-sendable
// metatypes.

View File

@@ -1,8 +1,7 @@
// RUN: %target-swift-frontend -primary-file %s -emit-ir -swift-version 6 -enable-experimental-feature IsolatedConformances | %FileCheck %s -DINT=i%target-ptrsize
// RUN: %target-swift-frontend -primary-file %s -emit-ir -swift-version 6 | %FileCheck %s -DINT=i%target-ptrsize
// REQUIRES: PTRSIZE=64
// REQUIRES: concurrency
// REQUIRES: swift_feature_IsolatedConformances
// UNSUPPORTED: CPU=arm64e
protocol P {

View File

@@ -1,6 +1,5 @@
// RUN: %target-swift-frontend -typecheck -swift-version 6 -enable-library-evolution -module-name isolated_conformance -enable-experimental-feature IsolatedConformances -emit-module-interface-path - %s | %FileCheck %s
// RUN: %target-swift-frontend -typecheck -swift-version 6 -enable-library-evolution -module-name isolated_conformance -emit-module-interface-path - %s | %FileCheck %s
// REQUIRES: swift_feature_IsolatedConformances
// REQUIRES: concurrency
public protocol MyProtocol {

View File

@@ -1,6 +1,5 @@
// RUN: %target-sil-opt -enable-sil-verify-all %s -diagnostic-constant-propagation -enable-experimental-feature IsolatedConformances | %FileCheck %s
// RUN: %target-sil-opt -enable-sil-verify-all %s -diagnostic-constant-propagation | %FileCheck %s
// REQUIRES: swift_feature_IsolatedConformances
// REQUIRES: concurrency
sil_stage canonical

View File

@@ -1,14 +1,14 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift -parse-as-library -O %s -enable-experimental-feature IsolatedConformances -o %t/a.out
// RUN: %target-build-swift -parse-as-library -O %s -o %t/a.out
// RUN: %target-codesign %t/a.out
// RUN: %target-run %t/a.out | %FileCheck %s --check-prefix=CHECK-OUTPUT
// RUN: %target-build-swift -parse-as-library -O %s -enable-experimental-feature IsolatedConformances -Xllvm -sil-disable-pass=function-signature-opts -emit-sil | %FileCheck %s
// RUN: %target-build-swift -parse-as-library -O %s -Xllvm -sil-disable-pass=function-signature-opts -emit-sil | %FileCheck %s
// REQUIRES: concurrency
// REQUIRES: executable_test
// REQUIRES: concurrency_runtime
// REQUIRES: swift_feature_IsolatedConformances
// REQUIRES: OS=macosx || OS=linux-gnu
// UNSUPPORTED: back_deployment_runtime
// UNSUPPORTED: back_deploy_concurrency

View File

@@ -1,6 +1,5 @@
// RUN: %target-sil-opt -enable-sil-verify-all %s -simplification -simplify-instruction=unconditional_checked_cast -enable-experimental-feature IsolatedConformances | %FileCheck %s
// RUN: %target-sil-opt -enable-sil-verify-all %s -simplification -simplify-instruction=unconditional_checked_cast | %FileCheck %s
// REQUIRES: swift_feature_IsolatedConformances
// REQUIRES: concurrency
import Swift

View File

@@ -1,9 +1,8 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -target %target-swift-5.1-abi-triple -swift-version 6 -enable-experimental-feature IsolatedConformances -o %t/def_isolated_conformance.swiftmodule %S/Inputs/def_isolated_conformance.swift
// RUN: %target-swift-frontend -emit-module -target %target-swift-5.1-abi-triple -swift-version 6 -o %t/def_isolated_conformance.swiftmodule %S/Inputs/def_isolated_conformance.swift
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -enable-experimental-feature IsolatedConformances %s -I %t
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 %s -I %t
// REQUIRES: swift_feature_IsolatedConformances
// REQUIRES: concurrency
import def_isolated_conformance