diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ee272369c8..05c0b540902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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(_ 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]: [#42697]: [#42728]: diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 12c44ff07a0..062b5bf76f1 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -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)) diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index 21e3af02aeb..b3c01fcf0eb 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -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) diff --git a/lib/AST/ConformanceLookup.cpp b/lib/AST/ConformanceLookup.cpp index dc02e369d7d..93d78317219 100644 --- a/lib/AST/ConformanceLookup.cpp +++ b/lib/AST/ConformanceLookup.cpp @@ -386,33 +386,30 @@ 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) { - Type instanceType = metatypeType->getInstanceType(); + auto sendableMetatypeProto = + ctx.getProtocol(KnownProtocolKind::SendableMetatype); + if (sendableMetatypeProto) { + Type instanceType = metatypeType->getInstanceType(); - // If the instance type is a type parameter, it is not necessarily - // Sendable. There will need to be a Sendable requirement. - if (instanceType->isTypeParameter()) - break; + // If the instance type is a type parameter, it is not necessarily + // Sendable. There will need to be a Sendable requirement. + if (instanceType->isTypeParameter()) + break; - // If the instance type conforms to SendableMetatype, then its - // metatype is Sendable. - auto instanceConformance = lookupConformance( - instanceType, sendableMetatypeProto); - if (instanceConformance.isInvalid() || - instanceConformance.hasMissingConformance()) - break; - } - - // Every other metatype is Sendable. + // If the instance type conforms to SendableMetatype, then its + // metatype is Sendable. + auto instanceConformance = lookupConformance( + instanceType, sendableMetatypeProto); + if (instanceConformance.isInvalid() || + instanceConformance.hasMissingConformance()) + break; } LLVM_FALLTHROUGH; + } case KnownProtocolKind::Copyable: case KnownProtocolKind::Escapable: diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp index 414b6056bac..5ac469fe59c 100644 --- a/lib/Parse/ParseType.cpp +++ b/lib/Parse/ParseType.cpp @@ -163,9 +163,7 @@ ParserResult Parser::parseTypeSimple( Diag<> MessageID, ParseTypeReason reason) { ParserResult 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()); diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index 640911ae563..fc32dad4122 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -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. diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 13abba03c1d..d12803a8554 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -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(); diff --git a/test/Concurrency/Runtime/isolated_conformance.swift b/test/Concurrency/Runtime/isolated_conformance.swift index ca3a3534404..bc795e22e59 100644 --- a/test/Concurrency/Runtime/isolated_conformance.swift +++ b/test/Concurrency/Runtime/isolated_conformance.swift @@ -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 diff --git a/test/Concurrency/isolated_conformance.swift b/test/Concurrency/isolated_conformance.swift index dd6416ec171..92343133eaa 100644 --- a/test/Concurrency/isolated_conformance.swift +++ b/test/Concurrency/isolated_conformance.swift @@ -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 { diff --git a/test/Concurrency/isolated_conformance_default_actor.swift b/test/Concurrency/isolated_conformance_default_actor.swift index 3b302234207..ce8cce07ecc 100644 --- a/test/Concurrency/isolated_conformance_default_actor.swift +++ b/test/Concurrency/isolated_conformance_default_actor.swift @@ -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 diff --git a/test/Concurrency/isolated_conformance_inference.swift b/test/Concurrency/isolated_conformance_inference.swift index ed0bc91ac2a..e513f3f8a77 100644 --- a/test/Concurrency/isolated_conformance_inference.swift +++ b/test/Concurrency/isolated_conformance_inference.swift @@ -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 { diff --git a/test/Concurrency/sendable_metatype.swift b/test/Concurrency/sendable_metatype.swift index a21366ac6f0..1371456d97e 100644 --- a/test/Concurrency/sendable_metatype.swift +++ b/test/Concurrency/sendable_metatype.swift @@ -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 { diff --git a/test/Concurrency/sendable_metatype_typecheck.swift b/test/Concurrency/sendable_metatype_typecheck.swift index 6ba6def4956..494ab2b8c9c 100644 --- a/test/Concurrency/sendable_metatype_typecheck.swift +++ b/test/Concurrency/sendable_metatype_typecheck.swift @@ -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. diff --git a/test/IRGen/isolated_conformance.swift b/test/IRGen/isolated_conformance.swift index 6240933188e..6900cf90573 100644 --- a/test/IRGen/isolated_conformance.swift +++ b/test/IRGen/isolated_conformance.swift @@ -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 { diff --git a/test/ModuleInterface/isolated_conformance.swift b/test/ModuleInterface/isolated_conformance.swift index 23d93fcdd45..9ed21b8b67e 100644 --- a/test/ModuleInterface/isolated_conformance.swift +++ b/test/ModuleInterface/isolated_conformance.swift @@ -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 { diff --git a/test/SILOptimizer/constant_propagation_casts_ossa.sil b/test/SILOptimizer/constant_propagation_casts_ossa.sil index c2ce3a3cfc8..875d0c9c7ab 100644 --- a/test/SILOptimizer/constant_propagation_casts_ossa.sil +++ b/test/SILOptimizer/constant_propagation_casts_ossa.sil @@ -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 diff --git a/test/SILOptimizer/isolated_conformances.swift b/test/SILOptimizer/isolated_conformances.swift index f51da74545c..2c5e66d0942 100644 --- a/test/SILOptimizer/isolated_conformances.swift +++ b/test/SILOptimizer/isolated_conformances.swift @@ -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 diff --git a/test/SILOptimizer/simplify_unconditional_check_cast.sil b/test/SILOptimizer/simplify_unconditional_check_cast.sil index 21134ec91a0..1b667b2e60d 100644 --- a/test/SILOptimizer/simplify_unconditional_check_cast.sil +++ b/test/SILOptimizer/simplify_unconditional_check_cast.sil @@ -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 diff --git a/test/Serialization/isolated_conformance.swift b/test/Serialization/isolated_conformance.swift index beeb48aa106..064bdf03345 100644 --- a/test/Serialization/isolated_conformance.swift +++ b/test/Serialization/isolated_conformance.swift @@ -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