Skip to content

Commit ad68d22

Browse files
authored
Merge pull request #76518 from slavapestov/fix-issue-76513
Concurrency: Reject nonisolated lazy properties
2 parents 9279ddf + 46b4983 commit ad68d22

File tree

4 files changed

+76
-17
lines changed

4 files changed

+76
-17
lines changed

include/swift/AST/DiagnosticsSema.def

+3
Original file line numberDiff line numberDiff line change
@@ -5810,6 +5810,9 @@ ERROR(nonisolated_actor_sync_init,none,
58105810
ERROR(nonisolated_wrapped_property,none,
58115811
"'nonisolated' is not supported on properties with property wrappers",
58125812
())
5813+
ERROR(nonisolated_lazy,none,
5814+
"'nonisolated' is not supported on lazy properties",
5815+
())
58135816

58145817
ERROR(non_sendable_from_deinit,none,
58155818
"cannot access %1 %2 with a non-sendable type %0 from nonisolated deinit",

lib/Sema/TypeCheckAttr.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -7224,15 +7224,22 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
72247224
}
72257225
}
72267226

7227-
// Using 'nonisolated' with wrapped properties is unsupported, because
7228-
// backing storage is a stored 'var' that is part of the internal state
7229-
// of the actor which could only be accessed in actor's isolation context.
7227+
// Using 'nonisolated' with lazy properties and wrapped properties is
7228+
// unsupported, because backing storage is a stored 'var' that is part
7229+
// of the internal state of the actor which could only be accessed in
7230+
// actor's isolation context.
72307231
if (var->hasAttachedPropertyWrapper()) {
72317232
diagnoseAndRemoveAttr(attr, diag::nonisolated_wrapped_property)
72327233
.warnUntilSwiftVersionIf(attr->isImplicit(), 6);
72337234
return;
72347235
}
72357236

7237+
if (var->getAttrs().hasAttribute<LazyAttr>()) {
7238+
diagnoseAndRemoveAttr(attr, diag::nonisolated_lazy)
7239+
.warnUntilSwiftVersionIf(attr->isImplicit(), 6);
7240+
return;
7241+
}
7242+
72367243
// nonisolated can not be applied to local properties unless qualified as
72377244
// 'unsafe'.
72387245
if (dc->isLocalContext() && !attr->isUnsafe()) {

test/Concurrency/actor_isolation.swift

+13-5
Original file line numberDiff line numberDiff line change
@@ -834,21 +834,29 @@ actor LazyActor {
834834
lazy var l25: Int = { [unowned self] in self.l }()
835835

836836
nonisolated lazy var l31: Int = { v }()
837-
// expected-warning@-1 {{actor-isolated default value in a nonisolated context; this is an error in the Swift 6 language mode}}
837+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
838+
// expected-warning@-2 {{actor-isolated default value in a nonisolated context; this is an error in the Swift 6 language mode}}
838839
nonisolated lazy var l32: Int = v
839-
// expected-warning@-1 {{actor-isolated default value in a nonisolated context; this is an error in the Swift 6 language mode}}
840+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
840841
nonisolated lazy var l33: Int = { self.v }()
841-
// expected-warning@-1 {{actor-isolated default value in a nonisolated context; this is an error in the Swift 6 language mode}}
842+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
843+
// expected-warning@-2 {{actor-isolated default value in a nonisolated context; this is an error in the Swift 6 language mode}}
842844
nonisolated lazy var l34: Int = self.v
843-
// expected-warning@-1 {{actor-isolated default value in a nonisolated context; this is an error in the Swift 6 language mode}}
845+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
844846
nonisolated lazy var l35: Int = { [unowned self] in self.v }()
845-
// expected-warning@-1 {{actor-isolated default value in a nonisolated context; this is an error in the Swift 6 language mode}}
847+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
848+
// expected-warning@-2 {{actor-isolated default value in a nonisolated context; this is an error in the Swift 6 language mode}}
846849

847850
nonisolated lazy var l41: Int = { l }()
851+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
848852
nonisolated lazy var l42: Int = l
853+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
849854
nonisolated lazy var l43: Int = { self.l }()
855+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
850856
nonisolated lazy var l44: Int = self.l
857+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
851858
nonisolated lazy var l45: Int = { [unowned self] in self.l }()
859+
// expected-error@-1 {{'nonisolated' is not supported on lazy properties}}
852860
}
853861

854862
// Infer global actors from context only for instance members.

test/Concurrency/mutable_storage_nonisolated.swift

+50-9
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,67 @@
22
// RUN: %target-swift-frontend -disable-availability-checking -strict-concurrency=complete -parse-as-library %s -emit-sil -o /dev/null -verify -strict-concurrency=complete
33

44
// REQUIRES: concurrency
5-
// REQUIRES: asserts
5+
6+
@propertyWrapper struct P {
7+
var wrappedValue = 0
8+
}
69

710
class NonSendable {}
811

912
struct ImplicitlySendable {
10-
var x: Int
11-
nonisolated var y: Int // okay
13+
var a: Int
14+
15+
// always okay
16+
nonisolated let b = 0
17+
nonisolated var c: Int { 0 }
18+
19+
// okay
20+
nonisolated var d = 0
21+
22+
// never okay
23+
nonisolated lazy var e = 0 // expected-error {{'nonisolated' is not supported on lazy properties}}
24+
@P nonisolated var f = 0 // expected-error {{'nonisolated' is not supported on properties with property wrappers}}
1225
}
1326

1427
struct ImplicitlyNonSendable {
15-
let x: NonSendable
16-
// expected-note@+1 {{convert 'y' to a 'let' constant or consider declaring it 'nonisolated(unsafe)' if manually managing concurrency safety}}
17-
nonisolated var y: Int // expected-error {{'nonisolated' cannot be applied to mutable stored properties}}
28+
let a: NonSendable
29+
30+
// always okay
31+
nonisolated let b = 0
32+
nonisolated var c: Int { 0 }
33+
34+
// not okay
35+
nonisolated var d = 0 // expected-error {{'nonisolated' cannot be applied to mutable stored properties}}
36+
// expected-note@-1 {{convert 'd' to a 'let' constant or consider declaring it 'nonisolated(unsafe)' if manually managing concurrency safety}}
37+
38+
// never okay
39+
nonisolated lazy var e = 0 // expected-error {{'nonisolated' is not supported on lazy properties}}
40+
@P nonisolated var f = 0 // expected-error {{'nonisolated' is not supported on properties with property wrappers}}
1841
}
1942

2043
public struct PublicSendable: Sendable {
21-
nonisolated var x: Int // okay
44+
// always okay
45+
nonisolated let b = 0
46+
nonisolated var c: Int { 0 }
47+
48+
// okay
49+
nonisolated var d = 0
50+
51+
// never okay
52+
nonisolated lazy var e = 0 // expected-error {{'nonisolated' is not supported on lazy properties}}
53+
@P nonisolated var f = 0 // expected-error {{'nonisolated' is not supported on properties with property wrappers}}
2254
}
2355

2456
public struct PublicNonSendable {
25-
// expected-note@+1 {{convert 'x' to a 'let' constant or consider declaring it 'nonisolated(unsafe)' if manually managing concurrency safety}}
26-
nonisolated var x: Int // expected-error {{'nonisolated' cannot be applied to mutable stored properties}}
57+
// always okay
58+
nonisolated let b = 0
59+
nonisolated var c: Int { 0 }
60+
61+
// not okay
62+
nonisolated var d = 0 // expected-error {{'nonisolated' cannot be applied to mutable stored properties}}
63+
// expected-note@-1 {{convert 'd' to a 'let' constant or consider declaring it 'nonisolated(unsafe)' if manually managing concurrency safety}}
64+
65+
// never okay
66+
nonisolated lazy var e = 0 // expected-error {{'nonisolated' is not supported on lazy properties}}
67+
@P nonisolated var f = 0 // expected-error {{'nonisolated' is not supported on properties with property wrappers}}
2768
}

0 commit comments

Comments
 (0)