Files
swift-mirror/stdlib/public/core/Sendable.swift
Doug Gregor e24598bca1 Use a marker protocol SendableMetatype to model T.Type: Sendable
Introduce a marker protocol SendableMetatype that is used to indicate
when the metatype of a type will conform to Sendable. Specifically,
`T: SendableMetatype` implies `T.Type: Sendable`. When strict
metatype sendability is enabled, metatypes are only sendable when `T:
SendableMetatype`.

All nominal types implicitly conform to `SendableMetatype`, as do the
various builtin types, function types, etc. The `Sendable` marker
protocol now inherits from `SendableMetatype`, so that `T: Sendable`
implies `T.Type: Sendable`.

Thank you Slava for the excellent idea!
2025-02-13 22:48:05 -08:00

159 lines
6.3 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
/// A type `T` whose metatype `T.Type` is `Sendable`.
@_marker public protocol SendableMetatype: ~Copyable, ~Escapable { }
/// A thread-safe type whose values can be shared across arbitrary concurrent
/// contexts without introducing a risk of data races. Values of the type may
/// have no shared mutable state, or they may protect that state with a lock or
/// by forcing it to only be accessed from a specific actor.
///
/// You can safely pass values of a sendable type
/// from one concurrency domain to another ---
/// for example, you can pass a sendable value as the argument
/// when calling an actor's methods.
/// All of the following can be marked as sendable:
///
/// - Value types
///
/// - Reference types with no mutable storage
///
/// - Reference types that internally manage access to their state
///
/// - Functions and closures (by marking them with `@Sendable`)
///
/// Although this protocol doesn't have any required methods or properties,
/// it does have semantic requirements that are enforced at compile time.
/// These requirements are listed in the sections below.
/// Conformance to `Sendable` must be declared
/// in the same file as the type's declaration.
///
/// To declare conformance to `Sendable` without any compiler enforcement,
/// write `@unchecked Sendable`.
/// You are responsible for the correctness of unchecked sendable types,
/// for example, by protecting all access to its state with a lock or a queue.
/// Unchecked conformance to `Sendable` also disables enforcement
/// of the rule that conformance must be in the same file.
///
/// For information about the language-level concurrency model that `Task` is part of,
/// see [Concurrency][concurrency] in [The Swift Programming Language][tspl].
///
/// [concurrency]: https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html
/// [tspl]: https://docs.swift.org/swift-book/
///
/// ### Sendable Structures and Enumerations
///
/// To satisfy the requirements of the `Sendable` protocol,
/// an enumeration or structure must have only sendable
/// members and associated values.
/// In some cases, structures and enumerations
/// that satisfy the requirements implicitly conform to `Sendable`:
///
/// - Frozen structures and enumerations
///
/// - Structures and enumerations
/// that aren't public and aren't marked `@usableFromInline`.
///
/// Otherwise, you need to declare conformance to `Sendable` explicitly.
///
/// Structures that have nonsendable stored properties
/// and enumerations that have nonsendable associated values
/// can be marked as `@unchecked Sendable`,
/// disabling compile-time correctness checks,
/// after you manually verify that
/// they satisfy the `Sendable` protocol's semantic requirements.
///
/// ### Sendable Actors
///
/// All actor types implicitly conform to `Sendable`
/// because actors ensure that all access to their mutable state
/// is performed sequentially.
///
/// ### Sendable Classes
///
/// To satisfy the requirements of the `Sendable` protocol,
/// a class must:
///
/// - Be marked `final`
///
/// - Contain only stored properties that are immutable and sendable
///
/// - Have no superclass or have `NSObject` as the superclass
///
/// Classes marked with `@MainActor` are implicitly sendable,
/// because the main actor coordinates all access to its state.
/// These classes can have stored properties that are mutable and nonsendable.
///
/// Classes that don't meet the requirements above
/// can be marked as `@unchecked Sendable`,
/// disabling compile-time correctness checks,
/// after you manually verify that
/// they satisfy the `Sendable` protocol's semantic requirements.
///
/// ### Sendable Functions and Closures
///
/// Instead of conforming to the `Sendable` protocol,
/// you mark sendable functions and closures with the `@Sendable` attribute.
/// Any values that the function or closure captures must be sendable.
/// In addition, sendable closures must use only by-value captures,
/// and the captured values must be of a sendable type.
///
/// In a context that expects a sendable closure,
/// a closure that satisfies the requirements
/// implicitly conforms to `Sendable` ---
/// for example, in a call to `Task.detached(priority:operation:)`.
///
/// You can explicitly mark a closure as sendable
/// by writing `@Sendable` as part of a type annotation,
/// or by writing `@Sendable` before the closure's parameters ---
/// for example:
///
/// let sendableClosure = { @Sendable (number: Int) -> String in
/// if number > 12 {
/// return "More than a dozen."
/// } else {
/// return "Less than a dozen"
/// }
/// }
///
/// ### Sendable Tuples
///
/// To satisfy the requirements of the `Sendable` protocol,
/// all of the elements of the tuple must be sendable.
/// Tuples that satisfy the requirements implicitly conform to `Sendable`.
///
/// ### Sendable Metatypes
///
/// Metatypes such as `Int.Type` implicitly conform to the `Sendable` protocol.
@_marker public protocol Sendable: SendableMetatype, ~Copyable, ~Escapable { }
///
/// A type whose values can safely be passed across concurrency domains by copying,
/// but which disables some safety checking at the conformance site.
///
/// Use an unchecked conformance to `Sendable` instead --- for example:
///
/// struct MyStructure: @unchecked Sendable { ... }
@available(*, deprecated, message: "Use @unchecked Sendable instead")
@available(swift, obsoleted: 6.0, message: "Use @unchecked Sendable instead")
@_marker public protocol UnsafeSendable: Sendable { }
// Historical names
@available(*, deprecated, renamed: "Sendable")
@available(swift, obsoleted: 6.0, renamed: "Sendable")
public typealias ConcurrentValue = Sendable
@available(*, deprecated, renamed: "Sendable")
@available(swift, obsoleted: 6.0, renamed: "Sendable")
public typealias UnsafeConcurrentValue = UnsafeSendable