/*:#localized(key: "NonSendableProblem")
 # Why a mutable class isn't Sendable, and how to fix it

 Now the case the whole protocol exists to catch. Imagine a shared scoreboard for
 the coffee bar's daily order count: a class, because we want one object everyone
 updates:

 ```swift
 final class OrderCount {
     var total = 0
 }

 let orders = OrderCount()

 // Hand the shared object to work running off the main actor:
 Task.detached {
     orders.total += 1   // will not compile in Swift 6
 }
 print(orders.total)
 ```

 In Swift 6's language mode this **does not compile.** The error is:
 *"non-Sendable type 'OrderCount' of let 'orders' cannot exit main actor-isolated
 context"*, with a note that `OrderCount` *"does not conform to the `Sendable`
 protocol."* The compiler sees a mutable class about to be handed to another
 isolation domain and stops you, *before* the race can ever happen. That's the
 shift from the classic model: the data race in the chapter [Concurrency Hazards](Concurrency%20Hazards.playgroundchapter/Overview) was a runtime
 surprise you had to reason about; here it's a compile error you can't miss.

 * callout(Try it): Imagine changing `Task.detached` above to a plain `Task { }`.
 Would the code compile? (It would; the next callout explains why.)

 * callout(Why this compiles): Top-level code, like a Playground page, runs *on
 the main actor*. A plain `Task { }` **inherits** that main-actor isolation, so
 the object never leaves its domain and the code actually compiles.
 `Task.detached` runs *outside* the main actor, and that boundary crossing is
 what makes sharing a mutable class unsafe. The lesson: the danger appears when
 mutable state **crosses between** domains, so that's where the compiler puts
 the tripwire.

 You have three honest ways to fix it:

 **1. Make it an actor** (best when the state must stay mutable and shared):
 */
//#-editable-code
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

actor OrderCount {
    private(set) var total = 0
    func increment() { total += 1 }
}

let orders = OrderCount()

Task.detached {
    await orders.increment()
    await orders.increment()
    print("Total orders: \(await orders.total)")
    PlaygroundPage.current.finishExecution()
}
//#-end-editable-code
/*:#localized(key: "NonSendableFixes")
 Actors are Sendable automatically; that's their job. Sharing one is always safe
 because the actor serializes every access.

 **2. Make it immutable** (best when the value never changes after creation):

 ```swift
 final class FrozenReceipt: Sendable {
     let id: Int
     let total: Int
     init(id: Int, total: Int) {
         self.id = id
         self.total = total
     }
 }
 ```

 `final` + all-`let` + Sendable members = a class you can safely share, because
 there's nothing to mutate.

 **3. Isolate it to an actor** (including `@MainActor`):
 
 Tag the type with a global actor so all access already funnels through one
 domain, which is exactly what `BalanceDisplay` did before.

 There's also an escape hatch, `@unchecked Sendable`, where *you* promise the
 type is safe (say, it guards its own state with a lock) and the compiler takes
 your word. Treat it as a last resort: the whole point of this chapter is to let
 the compiler do the checking, not to switch it off.

 [Previous](@previous)  |  page 8 of 11  |  [Next: Sendable Closures](@next)
 */
