Skip to content

Commit d595b15

Browse files
authored
Merge pull request #72070 from hborla/nonisolated-unsafe-fixes
[Concurrency] Fix an issue where `nonisolated(unsafe)` did not suppress concurrency warnings.
2 parents 082f2b0 + 75858cd commit d595b15

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,6 +2468,15 @@ namespace {
24682468
// If the closure won't execute concurrently with the context in
24692469
// which the declaration occurred, it's okay.
24702470
auto decl = capture.getDecl();
2471+
auto isolation = getActorIsolation(decl);
2472+
2473+
// 'nonisolated' local variables are always okay to capture in
2474+
// 'Sendable' closures because they can be accessed from anywhere.
2475+
// Note that only 'nonisolated(unsafe)' can be applied to local
2476+
// variables.
2477+
if (isolation.isNonisolated())
2478+
continue;
2479+
24712480
auto *context = localFunc.getAsDeclContext();
24722481
auto fnType = localFunc.getType()->getAs<AnyFunctionType>();
24732482
if (!mayExecuteConcurrentlyWith(context, decl->getDeclContext()))
@@ -5490,13 +5499,18 @@ static bool checkSendableInstanceStorage(
54905499

54915500
/// Handle a stored property.
54925501
bool operator()(VarDecl *property, Type propertyType) override {
5502+
ActorIsolation isolation = getActorIsolation(property);
5503+
5504+
// 'nonisolated' properties are always okay in 'Sendable' types because
5505+
// they can be accessed from anywhere. Note that 'nonisolated' without
5506+
// '(unsafe)' can only be applied to immutable, 'Sendable' properties.
5507+
if (isolation.isNonisolated())
5508+
return false;
5509+
54935510
// Classes with mutable properties are Sendable if property is
54945511
// actor-isolated
54955512
if (isa<ClassDecl>(nominal)) {
5496-
ActorIsolation isolation = getActorIsolation(property);
5497-
5498-
if (property->supportsMutation() &&
5499-
(isolation.isNonisolated() || isolation.isUnspecified())) {
5513+
if (property->supportsMutation() && isolation.isUnspecified()) {
55005514
auto behavior =
55015515
SendableCheckContext(dc, check).defaultDiagnosticBehavior();
55025516
if (behavior != DiagnosticBehavior::Ignore) {

test/Concurrency/sendable_checking.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,3 +361,18 @@ enum SynthesizedConformances {
361361
let x: NotSendable
362362
}
363363
}
364+
365+
@available(SwiftStdlib 5.1, *)
366+
final class UseNonisolatedUnsafe: Sendable {
367+
nonisolated(unsafe) var x1: NonSendable = .init()
368+
nonisolated(unsafe) let x2: NonSendable = .init()
369+
nonisolated(unsafe) var x3: Int = 0
370+
371+
func captureInTask() {
372+
nonisolated(unsafe) var x = NonSendable()
373+
Task {
374+
print(x)
375+
x = NonSendable()
376+
}
377+
}
378+
}

0 commit comments

Comments
 (0)