mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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!
159 lines
6.3 KiB
Swift
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
|