Skip to content

Commit 5e29333

Browse files
committed
[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 3380331)
1 parent 69758f6 commit 5e29333

19 files changed

+72
-70
lines changed

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,34 @@
3232
strategy, given that the code would eventually become ambiguous anyways when
3333
the deployment target is raised.
3434

35+
* [SE-0470][]:
36+
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:
37+
38+
```swift
39+
protocol P {
40+
func f()
41+
}
42+
43+
@MainActor
44+
class MyType: @MainActor P {
45+
/*@MainActor*/ func f() {
46+
// must be called on the main actor
47+
}
48+
}
49+
```
50+
51+
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:
52+
53+
```swift
54+
func acceptP<T: P>(_ value: T) { }
55+
56+
/*nonisolated*/ func useIsolatedConformance(myType: MyType) {
57+
acceptP(myType) // error: main actor-isolated conformance of 'MyType' to 'P' cannot be used in nonisolated context
58+
}
59+
```
60+
61+
To address such issues, only use an isolated conformance from code that executes on the same global actor.
62+
3563
* [SE-0419][]:
3664
Introduced the new `Runtime` module, which contains a public API that can
3765
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
1075910787
[SE-0442]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0442-allow-taskgroup-childtaskresult-type-to-be-inferred.md
1076010788
[SE-0444]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0444-member-import-visibility.md
1076110789
[SE-0458]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0458-strict-memory-safety.md
10790+
[SE-0470]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0470-isolated-conformances.md
1076210791
[#64927]: <https://github.com/apple/swift/issues/64927>
1076310792
[#42697]: <https://github.com/apple/swift/issues/42697>
1076410793
[#42728]: <https://github.com/apple/swift/issues/42728>

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8486,10 +8486,6 @@ ERROR(attr_abi_failable_mismatch,none,
84868486
//===----------------------------------------------------------------------===//
84878487
// MARK: Isolated conformances
84888488
//===----------------------------------------------------------------------===//
8489-
GROUPED_ERROR(isolated_conformance_experimental_feature,IsolatedConformances,
8490-
none,
8491-
"isolated conformances require experimental feature "
8492-
" 'IsolatedConformances'", ())
84938489
NOTE(note_isolate_conformance_to_global_actor,none,
84948490
"isolate this conformance to the %select{global actor %0|main actor}1 "
84958491
"with '@%2'", (Type, bool, StringRef))

include/swift/Basic/Features.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(MemorySafetyAttributes, 458, "@unsafe attribute")
254254
LANGUAGE_FEATURE(ValueGenerics, 452, "Value generics feature (integer generics)")
255255
LANGUAGE_FEATURE(RawIdentifiers, 451, "Raw identifiers")
256256
LANGUAGE_FEATURE(SendableCompletionHandlers, 463, "Objective-C completion handler parameters are imported as @Sendable")
257+
LANGUAGE_FEATURE(IsolatedConformances, 407, "Global-actor isolated conformances")
257258

258259
// Swift 6
259260
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
@@ -276,6 +277,7 @@ UPCOMING_FEATURE(GlobalActorIsolatedTypesUsability, 0434, 6)
276277
ADOPTABLE_UPCOMING_FEATURE(ExistentialAny, 335, 7)
277278
UPCOMING_FEATURE(InternalImportsByDefault, 409, 7)
278279
UPCOMING_FEATURE(MemberImportVisibility, 444, 7)
280+
UPCOMING_FEATURE(InferIsolatedConformances, 470, 7)
279281

280282
// Optional language features / modes
281283

@@ -495,6 +497,7 @@ ADOPTABLE_EXPERIMENTAL_FEATURE(AsyncCallerExecution, false)
495497
/// Allow custom availability domains to be defined and referenced.
496498
EXPERIMENTAL_FEATURE(CustomAvailability, true)
497499

500+
<<<<<<< HEAD
498501
/// Allow public enumerations to be extensible by default
499502
/// regardless of whether the module they are declared in
500503
/// is resilient or not.
@@ -506,6 +509,8 @@ EXPERIMENTAL_FEATURE(IsolatedConformances, true)
506509
/// Infer conformance isolation on global-actor-conforming types.
507510
EXPERIMENTAL_FEATURE(InferIsolatedConformances, true)
508511

512+
=======
513+
>>>>>>> 3380331e7eb ([SE-0470] Enable isolated conformances by default)
509514
/// Allow SwiftSettings
510515
EXPERIMENTAL_FEATURE(SwiftSettings, false)
511516

lib/AST/ConformanceLookup.cpp

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -386,33 +386,30 @@ static ProtocolConformanceRef getBuiltinMetaTypeTypeConformance(
386386
// All metatypes are Copyable, Escapable, and BitwiseCopyable.
387387
if (auto kp = protocol->getKnownProtocolKind()) {
388388
switch (*kp) {
389-
case KnownProtocolKind::Sendable:
389+
case KnownProtocolKind::Sendable: {
390390
// Metatypes are generally Sendable, but with isolated conformances we
391391
// cannot assume that metatypes based on type parameters are Sendable.
392392
// Therefore, check for conformance to SendableMetatype.
393-
if (ctx.LangOpts.hasFeature(Feature::IsolatedConformances)) {
394-
auto sendableMetatypeProto =
395-
ctx.getProtocol(KnownProtocolKind::SendableMetatype);
396-
if (sendableMetatypeProto) {
397-
Type instanceType = metatypeType->getInstanceType();
398-
399-
// If the instance type is a type parameter, it is not necessarily
400-
// Sendable. There will need to be a Sendable requirement.
401-
if (instanceType->isTypeParameter())
402-
break;
403-
404-
// If the instance type conforms to SendableMetatype, then its
405-
// metatype is Sendable.
406-
auto instanceConformance = lookupConformance(
407-
instanceType, sendableMetatypeProto);
408-
if (instanceConformance.isInvalid() ||
409-
instanceConformance.hasMissingConformance())
410-
break;
411-
}
412-
413-
// Every other metatype is Sendable.
393+
auto sendableMetatypeProto =
394+
ctx.getProtocol(KnownProtocolKind::SendableMetatype);
395+
if (sendableMetatypeProto) {
396+
Type instanceType = metatypeType->getInstanceType();
397+
398+
// If the instance type is a type parameter, it is not necessarily
399+
// Sendable. There will need to be a Sendable requirement.
400+
if (instanceType->isTypeParameter())
401+
break;
402+
403+
// If the instance type conforms to SendableMetatype, then its
404+
// metatype is Sendable.
405+
auto instanceConformance = lookupConformance(
406+
instanceType, sendableMetatypeProto);
407+
if (instanceConformance.isInvalid() ||
408+
instanceConformance.hasMissingConformance())
409+
break;
414410
}
415411
LLVM_FALLTHROUGH;
412+
}
416413

417414
case KnownProtocolKind::Copyable:
418415
case KnownProtocolKind::Escapable:

lib/Parse/ParseType.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,7 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(
163163
Diag<> MessageID, ParseTypeReason reason) {
164164
ParserResult<TypeRepr> ty;
165165

166-
if (isParameterSpecifier() &&
167-
!(!Context.LangOpts.hasFeature(Feature::IsolatedConformances) &&
168-
Tok.isContextualKeyword("isolated"))) {
166+
if (isParameterSpecifier()) {
169167
// Type specifier should already be parsed before here. This only happens
170168
// for construct like 'P1 & inout P2'.
171169
diagnose(Tok.getLoc(), diag::attr_only_on_parameters, Tok.getRawText());

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3021,10 +3021,9 @@ namespace {
30213021
// FIXME: When passing to a sending parameter, should this be handled
30223022
// by region isolation? Or should it always be handled by region
30233023
// isolation?
3024-
if (ctx.LangOpts.hasFeature(Feature::IsolatedConformances) &&
3025-
(mayExecuteConcurrentlyWith(
3024+
if (mayExecuteConcurrentlyWith(
30263025
localFunc.getAsDeclContext(), getDeclContext()) ||
3027-
(explicitClosure && explicitClosure->isPassedToSendingParameter()))) {
3026+
(explicitClosure && explicitClosure->isPassedToSendingParameter())) {
30283027
GenericSignature genericSig;
30293028
if (auto afd = localFunc.getAbstractFunctionDecl())
30303029
genericSig = afd->getGenericSignature();
@@ -7931,8 +7930,6 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
79317930

79327931
auto dc = rootNormal->getDeclContext();
79337932
ASTContext &ctx = dc->getASTContext();
7934-
if (!ctx.LangOpts.hasFeature(Feature::IsolatedConformances))
7935-
return ActorIsolation::forNonisolated(false);
79367933

79377934
// If the protocol itself is isolated, don't infer isolation for the
79387935
// conformance.

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,13 +2567,6 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
25672567
ComplainLoc, diag::unchecked_conformance_not_special, ProtoType);
25682568
}
25692569

2570-
// Complain if the global-actor-isolated conformances are not enabled.
2571-
if (conformance->isIsolated() &&
2572-
!Context.LangOpts.hasFeature(Feature::IsolatedConformances)) {
2573-
Context.Diags.diagnose(
2574-
ComplainLoc, diag::isolated_conformance_experimental_feature);
2575-
}
2576-
25772570
bool allowImpliedConditionalConformance = false;
25782571
if (Proto->isSpecificProtocol(KnownProtocolKind::Sendable)) {
25792572
// In -swift-version 5 mode, a conditional conformance to a protocol can imply
@@ -4978,8 +4971,7 @@ static void diagnoseConformanceIsolationErrors(
49784971
}
49794972

49804973
// Suggest isolating the conformance, if possible.
4981-
if (ctx.LangOpts.hasFeature(Feature::IsolatedConformances) &&
4982-
potentialIsolation && potentialIsolation->isGlobalActor() &&
4974+
if (potentialIsolation && potentialIsolation->isGlobalActor() &&
49834975
!conformance->isIsolated()) {
49844976
bool isMainActor = false;
49854977
Type globalActorIsolation = potentialIsolation->getGlobalActor();

test/Concurrency/Runtime/isolated_conformance.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
// RUN: %target-run-simple-swift(-enable-experimental-feature IsolatedConformances -target %target-swift-5.1-abi-triple) | %FileCheck %s
1+
// RUN: %target-run-simple-swift(-target %target-swift-5.1-abi-triple) | %FileCheck %s
22

33
// REQUIRES: executable_test
44
// REQUIRES: concurrency
55
// REQUIRES: concurrency_runtime
6-
// REQUIRES: swift_feature_IsolatedConformances
76
// UNSUPPORTED: back_deployment_runtime
87

98
// FIXME: WebAssembly doesn't currently have a good way to install the

test/Concurrency/isolated_conformance.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 5 -strict-concurrency=complete -enable-experimental-feature IsolatedConformances %s
1+
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 5 -strict-concurrency=complete %s
22

3-
// REQUIRES: swift_feature_IsolatedConformances
43
// REQUIRES: concurrency
54

65
protocol P {

test/Concurrency/isolated_conformance_default_actor.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -enable-experimental-feature IsolatedConformances -default-isolation MainActor %s
1+
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -default-isolation MainActor %s
22

3-
// REQUIRES: swift_feature_IsolatedConformances
43
// REQUIRES: concurrency
54

65
nonisolated

0 commit comments

Comments
 (0)