Skip to content

Commit 686b10e

Browse files
authored
[SE-0306] Update detach to Task.detached (#2533)
1 parent f75942d commit 686b10e

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

proposals/0306-actors.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ The restrictions on cross-actor references only work so long as we can ensure th
262262
extension BankAccount {
263263
func endOfMonth(month: Int, year: Int) {
264264
// Schedule a task to prepare an end-of-month report.
265-
detach {
265+
Task.detached {
266266
let transactions = await self.transactions(month: month, year: year)
267267
let report = Report(accountNumber: self.accountNumber, transactions: transactions)
268268
await report.email(to: self.accountOwnerEmailAddress)
@@ -271,7 +271,7 @@ extension BankAccount {
271271
}
272272
```
273273

274-
A task created with `detach` runs concurrently with all other code. If the closure passed to `detach` were to be actor-isolated, we would introduce a data race on access to the mutable state on `BankAccount`. Actors prevent this data race by specifying that a `@Sendable` closure (described in [`Sendable` and `@Sendable` closures][se302], and used in the definition of `detach` in the [Structured Concurrency][sc] proposal) is always non-isolated. Therefore, it is required to asynchronously access any actor-isolated declarations.
274+
A task created with `Task.detached` runs concurrently with all other code. If the closure passed to `Task.detached` were to be actor-isolated, we would introduce a data race on access to the mutable state on `BankAccount`. Actors prevent this data race by specifying that a `@Sendable` closure (described in [`Sendable` and `@Sendable` closures][se302], and used in the definition of `Task.detached` in the [Structured Concurrency][sc] proposal) is always non-isolated. Therefore, it is required to asynchronously access any actor-isolated declarations.
275275

276276
A closure that is not `@Sendable` cannot escape the concurrency domain in which it was formed. Therefore, such a closure will be actor-isolated if it is formed within an actor-isolated context. This is useful, for example, when applying sequence algorithms like `forEach` where the provided closure will be called serially:
277277

@@ -292,7 +292,7 @@ extension BankAccount {
292292

293293
A closure formed within an actor-isolated context is actor-isolated if it is non-`@Sendable`, and non-isolated if it is `@Sendable`. For the examples above:
294294

295-
* The closure passed to `detach` is non-isolated because that function requires a `@Sendable` function to be passed to it.
295+
* The closure passed to `Task.detached` is non-isolated because that function requires a `@Sendable` function to be passed to it.
296296
* The closure passed to `forEach` is actor-isolated to `self` because it takes a non-`@Sendable` function.
297297

298298
### Actor reentrancy
@@ -333,8 +333,8 @@ In the example above the `DecisionMaker` can think of a good or bad idea, shares
333333
This is exemplified by the following piece of code, exercising the `decisionMaker` actor:
334334

335335
```swift
336-
let goodThink = detach { await decisionMaker.thinkOfGoodIdea() } // runs async
337-
let badThink = detach { await decisionMaker.thinkOfBadIdea() } // runs async
336+
let goodThink = Task.detached { await decisionMaker.thinkOfGoodIdea() } // runs async
337+
let badThink = Task.detached { await decisionMaker.thinkOfBadIdea() } // runs async
338338

339339
let shouldBeGood = await goodThink.get()
340340
let shouldBeBad = await badThink.get()
@@ -599,7 +599,7 @@ actor A {
599599

600600
func useAF(array: [Int]) {
601601
array.map(self.f) // okay
602-
detach(operation: self.g) // error: self.g has non-sendable type () -> Double that cannot be converted to a @Sendable function type
602+
Task.detached(operation: self.g) // error: self.g has non-sendable type () -> Double that cannot be converted to a @Sendable function type
603603
runLater(self.g) // error: cannot convert value of non-sendable function type () -> Double to sendable function type
604604
}
605605
}
@@ -612,7 +612,7 @@ These restrictions follow from the actor isolation rules for the "desugaring" of
612612
extension A {
613613
func useAFDesugared(a: A, array: [Int]) {
614614
array.map { f($0) } ) // okay
615-
detach { g() } // error: self is non-isolated, so call to `g` cannot be synchronous
615+
Task.detached { g() } // error: self is non-isolated, so call to `g` cannot be synchronous
616616
runLater { g() } // error: self is non-isolated, so the call to `g` cannot be synchronous
617617
}
618618
}
@@ -879,7 +879,7 @@ The original accepted version of this proposal required *all* access to immutabl
879879
let total = 100
880880
var counter = 0
881881

882-
asyncDetached {
882+
Task.detached {
883883
print(total) // okay to reference immutable state
884884
print(counter) // error, cannot reference a `var` from a @Sendable closure
885885
}
@@ -900,7 +900,7 @@ By allowing synchronous access to actor `let`s within a module, we provide a smo
900900
* Escaping closures can now be actor-isolated; only `@Sendable` prevents isolation.
901901
* Removed actor inheritance. It can be considered at some future point.
902902
* Added "cross-actor lets" to Alternatives Considered. While there is no change to the proposed direction, the issue is explained here for further discussion.
903-
* Replaced `Task.runDetached` with `detach` to match updates to the [Structured Concurrency proposal][sc].
903+
* Replaced `detach` with `Task.detached` to match updates to the [Structured Concurrency proposal][sc].
904904
* Changes in the seventh pitch:
905905
* Removed isolated parameters and `nonisolated` from this proposal. They'll come in a follow-up proposal on [controlling actor isolation][isolationcontrol].
906906
* Changes in the sixth pitch:

0 commit comments

Comments
 (0)