Skip to content

Commit 2ae159b

Browse files
authored
Merge pull request swiftlang#70858 from angela-laar/actor-isolated-properties-for-classes
[Sema] Classes with actor-isolated mutable properties should conform to Sendable
2 parents fe39e69 + c779f37 commit 2ae159b

File tree

2 files changed

+38
-12
lines changed

2 files changed

+38
-12
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5334,22 +5334,28 @@ static bool checkSendableInstanceStorage(
53345334

53355335
/// Handle a stored property.
53365336
bool operator()(VarDecl *property, Type propertyType) override {
5337-
// Classes with mutable properties are not Sendable.
5338-
if (property->supportsMutation() && isa<ClassDecl>(nominal)) {
5339-
if (isImplicitSendableCheck(check)) {
5340-
invalid = true;
5337+
// Classes with mutable properties are Sendable if property is
5338+
// actor-isolated
5339+
if (isa<ClassDecl>(nominal)) {
5340+
ActorIsolation isolation = getActorIsolation(property);
5341+
5342+
if (property->supportsMutation() &&
5343+
(isolation.isNonisolated() || isolation.isUnspecified())) {
5344+
auto behavior =
5345+
SendableCheckContext(dc, check).defaultDiagnosticBehavior();
5346+
if (behavior != DiagnosticBehavior::Ignore) {
5347+
property
5348+
->diagnose(diag::concurrent_value_class_mutable_property,
5349+
property->getName(), nominal)
5350+
.limitBehavior(behavior);
5351+
}
5352+
invalid = invalid || (behavior == DiagnosticBehavior::Unspecified);
53415353
return true;
53425354
}
53435355

5344-
auto behavior = SendableCheckContext(
5345-
dc, check).defaultDiagnosticBehavior();
5346-
if (behavior != DiagnosticBehavior::Ignore) {
5347-
property->diagnose(diag::concurrent_value_class_mutable_property,
5348-
property->getName(), nominal)
5349-
.limitBehavior(behavior);
5356+
if (!(isolation.isNonisolated() || isolation.isUnspecified())) {
5357+
return false; // skip sendable check on actor-isolated properties
53505358
}
5351-
invalid = invalid || (behavior == DiagnosticBehavior::Unspecified);
5352-
return true;
53535359
}
53545360

53555361
// Check that the property type is Sendable.

test/Concurrency/concurrent_value_checking.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,26 @@ final class C7<T>: Sendable { }
342342

343343
class C9: Sendable { } // expected-warning{{non-final class 'C9' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
344344

345+
@globalActor
346+
struct SomeActor {
347+
static let shared = A1()
348+
}
349+
350+
class NotSendable {}
351+
352+
// actor-isolated mutable properties are valid
353+
final class C10: Sendable {
354+
@MainActor var x = 0
355+
@MainActor var ns1 : NotSendable?
356+
@MainActor let ns : NotSendable? = nil
357+
}
358+
359+
final class C14: Sendable {
360+
@SomeActor var y = 1
361+
@SomeActor var nc = NotConcurrent()
362+
@SomeActor let nc1 = NotConcurrent()
363+
}
364+
345365
extension NotConcurrent {
346366
func f() { }
347367

0 commit comments

Comments
 (0)