File: nonisolated_rules.swift

package info (click to toggle)
swiftlang 6.1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,791,532 kB
  • sloc: cpp: 9,901,743; ansic: 2,201,431; asm: 1,091,827; python: 308,252; objc: 82,166; f90: 80,126; lisp: 38,358; pascal: 25,559; sh: 20,429; ml: 5,058; perl: 4,745; makefile: 4,484; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (168 lines) | stat: -rw-r--r-- 4,464 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -swift-version 6 -parse-as-library %s -emit-sil -o /dev/null -verify -strict-concurrency=complete

// REQUIRES: concurrency

@MainActor
protocol GloballyIsolated {}

// expected-note@+1 {{class 'NonSendable' does not conform to the 'Sendable' protocol}}
class NonSendable {}

@propertyWrapper struct P {
  var wrappedValue = 0
}

// MARK: - Structs

struct ImplicitlySendable {
  var a: Int

  // always okay
  nonisolated let b = 0
  nonisolated var c: Int { 0 }
  nonisolated var d = 0

  // never okay
  nonisolated lazy var e = 0  // expected-error {{'nonisolated' is not supported on lazy properties}}
  @P nonisolated var f = 0  // expected-error {{'nonisolated' is not supported on properties with property wrappers}}
}

struct ImplicitlyNonSendable {
  let a: NonSendable

  // always okay
  nonisolated let b = 0
  nonisolated var c: Int { 0 }
  nonisolated var d = 0

  // never okay
  nonisolated lazy var e = 0  // expected-error {{'nonisolated' is not supported on lazy properties}}
  @P nonisolated var f = 0  // expected-error {{'nonisolated' is not supported on properties with property wrappers}}
}

public struct PublicSendable: Sendable {
  // always okay
  nonisolated let b = 0
  nonisolated var c: Int { 0 }
  nonisolated var d = 0

  // never okay
  nonisolated lazy var e = 0  // expected-error {{'nonisolated' is not supported on lazy properties}}
  @P nonisolated var f = 0  // expected-error {{'nonisolated' is not supported on properties with property wrappers}}
}

public struct PublicNonSendable {
  // always okay
  nonisolated let b = 0
  nonisolated var c: Int { 0 }
  nonisolated var d = 0

  // never okay
  nonisolated lazy var e = 0  // expected-error {{'nonisolated' is not supported on lazy properties}}
  @P nonisolated var f = 0  // expected-error {{'nonisolated' is not supported on properties with property wrappers}}
}


nonisolated struct NonisolatedStruct: GloballyIsolated {
  var x: NonSendable
  var y: Int = 1

  init(x: NonSendable) {
    self.x = x // okay
  }

  struct Nested: GloballyIsolated {
    // expected-note@+1 {{mutation of this property is only permitted within the actor}}
    var z: NonSendable
    nonisolated init(z: NonSendable) {
      // expected-error@+1 {{main actor-isolated property 'z' can not be mutated from a nonisolated context}}
      self.z = z
    }
  }
}

@MainActor struct S {
  var value: NonSendable // globally-isolated
  struct Nested {} // 'Nested' is not @MainActor-isolated
}

// expected-note@+1 {{calls to global function 'requireMain()' from outside of its actor context are implicitly asynchronous}}
@MainActor func requireMain() {}

nonisolated struct S1: GloballyIsolated {
  var x: NonSendable
  func f() {
    // expected-error@+1 {{call to main actor-isolated global function 'requireMain()' in a synchronous nonisolated context}}
    requireMain()
  }
}

// MARK: - Protocols

nonisolated protocol Refined: GloballyIsolated {}

struct A: Refined {
  var x: NonSendable
  init(x: NonSendable) {
    self.x = x // okay
  }
}

// MARK: - Extensions

nonisolated extension GloballyIsolated {
  var x: NonSendable { .init () }
  func implicitlyNonisolated() {}
}

struct C: GloballyIsolated {
  nonisolated func explicitlyNonisolated() {
    let _ = x // okay
    implicitlyNonisolated() // okay
  }
}

// MARK: - Enums

nonisolated enum E: GloballyIsolated {
  func implicitlyNonisolated() {}
  init() {}
}

struct TestEnum {
  nonisolated func call() {
    E().implicitlyNonisolated() // okay
  }
}

// MARK: - Classes

nonisolated class K: GloballyIsolated {
  var x: NonSendable
  init(x: NonSendable) {
    self.x = x // okay
  }
}

// MARK: - Storage of non-Sendable

class KlassA {
  nonisolated var test: NonSendable = NonSendable()
}

// MARK: - Restrictions

@MainActor
nonisolated struct Conflict {}
// expected-error@-1 {{struct 'Conflict' has multiple actor-isolation attributes ('nonisolated' and 'MainActor')}}

struct B: Sendable {
  // expected-error@+1 {{'nonisolated' can not be applied to variable with non-'Sendable' type 'NonSendable}}
  nonisolated let test: NonSendable
}

final class KlassB: Sendable {
  // expected-note@+2 {{convert 'test' to a 'let' constant or consider declaring it 'nonisolated(unsafe)' if manually managing concurrency safety}}
  // expected-error@+1 {{'nonisolated' cannot be applied to mutable stored properties}}
  nonisolated var test: Int = 1
}