Skip to content

Commit 662e30e

Browse files
committed
[Sema] Sendable classes should allow actor-isolated mutable properties
1 parent 4b8e41b commit 662e30e

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5219,22 +5219,29 @@ static bool checkSendableInstanceStorage(
52195219

52205220
/// Handle a stored property.
52215221
bool operator()(VarDecl *property, Type propertyType) override {
5222-
// Classes with mutable properties are not Sendable.
5222+
// Classes with mutable properties are not Sendable unless property is
5223+
// actor-isolated
52235224
if (property->supportsMutation() && isa<ClassDecl>(nominal)) {
5224-
if (isImplicitSendableCheck(check)) {
5225-
invalid = true;
5226-
return true;
5227-
}
5225+
ActorIsolation isolation = getActorIsolation(property);
52285226

5229-
auto behavior = SendableCheckContext(
5230-
dc, check).defaultDiagnosticBehavior();
5231-
if (behavior != DiagnosticBehavior::Ignore) {
5232-
property->diagnose(diag::concurrent_value_class_mutable_property,
5233-
property->getName(), nominal)
5234-
.limitBehavior(behavior);
5227+
if (isolation.getKind() == ActorIsolation::Kind::Nonisolated ||
5228+
isolation.getKind() == ActorIsolation::Kind::Unspecified) {
5229+
if (isImplicitSendableCheck(check)) {
5230+
invalid = true;
5231+
return true;
5232+
}
5233+
5234+
auto behavior =
5235+
SendableCheckContext(dc, check).defaultDiagnosticBehavior();
5236+
if (behavior != DiagnosticBehavior::Ignore) {
5237+
property
5238+
->diagnose(diag::concurrent_value_class_mutable_property,
5239+
property->getName(), nominal)
5240+
.limitBehavior(behavior);
5241+
}
5242+
invalid = invalid || (behavior == DiagnosticBehavior::Unspecified);
5243+
return true;
52355244
}
5236-
invalid = invalid || (behavior == DiagnosticBehavior::Unspecified);
5237-
return true;
52385245
}
52395246

52405247
// Check that the property type is Sendable.

test/Concurrency/concurrent_value_checking.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,21 @@ final class C7<T>: Sendable { }
341341

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

344+
@globalActor
345+
struct SomeActor {
346+
static var shared = A1()
347+
}
348+
// actor-isolated mutable properties are valid
349+
final class C10: Sendable {
350+
@MainActor var x = 0
351+
@SomeActor var y = 1
352+
}
353+
354+
// 'nonisolated (unsafe)' mutable properties are valid
355+
final class C13: Sendable {
356+
nonisolated (unsafe) var z = 2
357+
}
358+
344359
extension NotConcurrent {
345360
func f() { }
346361

0 commit comments

Comments
 (0)