/*:#localized(key: "Sendable")
 # `Sendable`: which values are safe to hand across a boundary

 Every time work crosses a concurrency boundary (into a `Task`, onto an actor,
 between two tasks), a value gets passed from one isolation domain to another.
 The question Swift must answer is: **is this value safe to share like that?**
 The answer is a protocol.

 **`Sendable` is the protocol marking a type as safe to pass across concurrency
 boundaries**: safe because sharing it can't cause a data race.

 Which types qualify?

 * **Value types** (structs, enums) are Sendable when all their members are
 Sendable. Because they're *copied* on assignment, two domains get two separate
 copies: nothing shared, nothing to race. Most of your structs are Sendable
 automatically; you rarely write the word.
 * **Immutable final classes** can be Sendable. If a class is `final` and every
 stored property is a `let` of a Sendable type, there's no mutable shared state,
 so sharing the reference is safe.
 * **Classes with mutable state are *not* Sendable.** A class is a *reference*:
 hand it to two domains and they share one object. If either mutates it, that's
 the classic data race from the chapter [Concurrency Hazards](Concurrency%20Hazards.playgroundchapter/Overview). Swift refuses to call such a type
 Sendable, and that refusal is the feature.

 Here's a plain value type that's Sendable with no effort. The annotation is
 optional (Swift infers it) but shown for clarity:
 */
//#-editable-code
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

struct Receipt: Sendable {
    let id: Int
    let total: Int
}

let receipt = Receipt(id: 1, total: 25)

Task {
    print("Received receipt #\(receipt.id) for \(receipt.total) across the task boundary")
    PlaygroundPage.current.finishExecution()
}
//#-end-editable-code
/*:#localized(key: "SendableNotice")
 You can pass a `Receipt` into any task freely; each side gets its own copy.

 [Previous](@previous)  |  page 7 of 11  |  [Next: Fixing a Non-Sendable Type](@next)
 */
