File: unsafe_inherit_executor.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (178 lines) | stat: -rw-r--r-- 6,479 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
169
170
171
172
173
174
175
176
177
178
// RUN: %target-swift-frontend -plugin-path %swift-plugin-dir -emit-sil -o /dev/null -verify -disable-availability-checking %s
// RUN: %target-swift-frontend -plugin-path %swift-plugin-dir -emit-sil -o /dev/null -verify -disable-availability-checking %s -strict-concurrency=targeted
// RUN: %target-swift-frontend -plugin-path %swift-plugin-dir -emit-sil -o /dev/null -verify -disable-availability-checking %s -strict-concurrency=complete
// RUN: %target-swift-frontend -plugin-path %swift-plugin-dir -emit-sil -o /dev/null -verify -disable-availability-checking %s -strict-concurrency=complete -enable-upcoming-feature RegionBasedIsolation

// REQUIRES: asserts

// expected-error @+1 {{non-async functions cannot inherit an executor}}
@_unsafeInheritExecutor
func testNonAsync() {}

@_unsafeInheritExecutor
func testAsync() async {}
// expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}

struct A {
  // expected-error @+1 {{@_unsafeInheritExecutor may only be used on 'func' declarations}}
  @_unsafeInheritExecutor
  init() async {}

  // expected-error @+1 {{non-async functions cannot inherit an executor}}
  @_unsafeInheritExecutor
  func testNonAsync() {}

  @_unsafeInheritExecutor
  func testAsync() async {}
  // expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}
}


class NonSendableObject {
  var property = 0
}

@_unsafeInheritExecutor
func useNonSendable(object: NonSendableObject) async {}
// expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead; this is an error in the Swift 6 language mode}}{{35:1-24=}}{{36:46-46=, isolation: isolated (any Actor)? = #isolation}}

actor MyActor {
  var object = NonSendableObject()
  func foo() async {
    await useNonSendable(object: self.object)
  }
}

// Note: the tests below are line-number-sensitive.
func inheritsIsolationProperly(isolation: isolated (any Actor)? = #isolation) async { }

// @_unsafeInheritExecutor does not work with #isolation
@_unsafeInheritExecutor
func unsafeCallerA(x: Int) async {
  // expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}

  await inheritsIsolationProperly()
  // expected-error@-1{{#isolation (introduced by a default argument) cannot be used within an '@_unsafeInheritExecutor' function}}{{50:1-24=}}{{51:26-26=, isolation: isolated (any Actor)? = #isolation}}
}

@_unsafeInheritExecutor
func unsafeCallerB() async {
  // expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}

  await inheritsIsolationProperly(isolation: #isolation)
  // expected-error@-1{{#isolation cannot be used within an '@_unsafeInheritExecutor' function}}{{58:1-24=}}{{59:20-20=isolation: isolated (any Actor)? = #isolation}}
}

@_unsafeInheritExecutor
func unsafeCallerC(x: Int, fn: () -> Void, fn2: () -> Void) async {
  // expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}

  await inheritsIsolationProperly()
  // expected-error@-1{{#isolation (introduced by a default argument) cannot be used within an '@_unsafeInheritExecutor' function}}{{66:1-24=}}{{67:28-28=, isolation: isolated (any Actor)? = #isolation, }}
}

@_unsafeInheritExecutor
func unsafeCallerAvoidsNewLoop(x: some AsyncSequence<Int, Never>) async throws {
  // expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}

  for try await _ in x { }
}

// -------------------------------------------------------------------------
// Type checker hack to use _unsafeInheritExecutor_-prefixed versions of
// some concurrency library functions.
// -------------------------------------------------------------------------

enum TL {
  @TaskLocal
  static var string: String = "<undefined>"
}

enum MyError: Error {
case fail
}

@_unsafeInheritExecutor
func unsafeCallerAvoidsNewLoop(clock: some Clock) async throws {
  // expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}

  _ = await withUnsafeContinuation { (continuation: UnsafeContinuation<Int, Never>) in
    continuation.resume(returning: 5)
  }

  _ = try await withUnsafeThrowingContinuation { (continuation: UnsafeContinuation<Int, any Error>) in
    continuation.resume(returning: 5)
  }

  _ = await withCheckedContinuation { (continuation: CheckedContinuation<Int, Never>) in
    continuation.resume(returning: 5)
  }

  _ = try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Int, any Error>) in
    continuation.resume(returning: 5)
  }

  _ = await withTaskCancellationHandler {
    5
  } onCancel: {
  }

  TL.$string.withValue("hello") {
    print(TL.string)
  }

  try await TL.$string.withValue("hello") {
    try await Task.sleep(nanoseconds: 500)
    print(TL.string)
  }

  func operation() async throws -> Int { 7 }
  try await TL.$string.withValue("hello", operation: operation)

  // FIXME: Clock.measure does not currently support this hack.
  // expected-error@+1{{#isolation (introduced by a default argument) cannot be used within an '@_unsafeInheritExecutor' function}}
  _ = try! await clock.measure {
    print("so very slow")
    try await Task.sleep(nanoseconds: 500)
  }

  _ = await withDiscardingTaskGroup(returning: Int.self) { group in
    group.addTask {
      print("hello")
    }

    return 5
  }

  _ = try await withThrowingDiscardingTaskGroup(returning: Int.self) { group in
    group.addTask {
      print("hello")
    }

    return 5
  }

  _ = await withTaskExecutorPreference(nil) {
    print("hello")
  }

  _ = await withTaskGroup(of: Int.self, returning: Int.self) { group in
    group.addTask {
      return 5
    }

    return 5
  }

  _ = try await withThrowingTaskGroup(of: Int.self, returning: Int.self) { group in
    group.addTask {
      throw MyError.fail
    }

    throw MyError.fail
  }
}

@_unsafeInheritExecutor
func _unsafeInheritExecutor_hacky() async { }
// expected-warning@-1{{@_unsafeInheritExecutor attribute is deprecated; consider an 'isolated' parameter defaulted to '#isolation' instead}}