[Accepted] SE-0302: Sendable and @Sendable closures

The second review of SE-0302 has concluded.

Feedback in the second round of review was generally positive. There was a fair amount of discussion about the new names, and people seemed to generally approve of the name Sendable for the protocol. Consensus was weaker about the name @sendable for the function-type attribute; the Core Team discussed this and decided to steal an idea from Matthew Johnson and rename the attribute to @Sendable. This name better emphasizes the core idea of the attribute (that so-modified function values have to conform to Sendable, and thus their captures must, too), and it also aligns with an interesting future direction (to allow similar protocol-based constraints on specific function types). The review was briefly extended, and feedback on that rename was strongly positive. Accordingly, SE-0302 is accepted with that modification.

Thank you for helping make Swift a better language.

John McCall
Review Manager

17 Likes

Did the core team discuss or have clarifications regarding the point raised during review about implicit conformance for frozen types? The proposal text reads:

For non-public, non-frozen structs and enums, the Sendable conformance is implicitly provided [...]
Public non-frozen structs and enums do not get an implicit conformance, because doing so would present a problem for API resilience

What is the behavior proposed/accepted here for non-public frozen structs and enums, and for public frozen structs and enums? The first sentence above implies that only non-public, non-frozen structs and enums would have implicit conformance, but the rationale given in the second sentence about problems for API resilience suggests that only public, non-frozen structs and enums would not get implicit conformance. The text does not exhaustively switch over all the possible combinations here, if you will.

I've asked Doug to chime in, but I believe the answer is that a type can have a conformance to Sendable potentially inferred if it is not publicly ABI-exposed (that is, not public, open, or @usableFromInline) or if it is a frozen struct or enum. If that seems sufficiently clarifying, we can update the proposal.

5 Likes

I put up a small pull request with this clarification: [SE-0302] Clarify inference for non-public structs and enums and frozen public structs and enums by DougGregor · Pull Request #1303 · apple/swift-evolution · GitHub

Doug

2 Likes

@Douglas_Gregor, was there any movement or core team feedback since the review period in terms of the following items raised by @Joe_Groff, @orobio, and me which you had responded favorably to?

1 Like

Interestingly, the idea of a function type conforming to a protocol is already expressible, it just doesn't compile:

((String) -> Int) & Sendable

This admittedly reads very poorly, so maybe it's for the best this isn't going to be the primary way of expressing the constraint. But it would intuitively make sense that this syntax could work, at least with marker protocols, and perhaps allow for Sendable-closure typealiases.

5 Likes

I think left part might be interpreted as a tuple of one function type :) However if you express function type as a typealias, it might be legit then

By design, tuples of one item are not expressible in Swift and if one should somehow arise, it would be considered identical to the one element type. A good reason for this is that it allows parentheses to be used unambiguously in type expressions, and this need already exists for cases like (() -> Void)!

5 Likes