Skip to content

Commit 1ac77fa

Browse files
authored
Merge branch 'swiftlang:main' into patch-1
2 parents c12d4df + a60ff28 commit 1ac77fa

6 files changed

+93
-28
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Welcome to the Swift community!
22

3-
Contributions to Swift are welcomed and encouraged! Please see the [Contributing to Swift guide](swift.org/contributing) and check out the [structure of the community](https://www.swift.org/community/#community-structure).
3+
Contributions to Swift are welcomed and encouraged! Please see the [Contributing to Swift guide](https://www.swift.org/contributing/) and check out the [structure of the community](https://www.swift.org/community/#community-structure).
44

55
To be a truly great community, Swift needs to welcome developers from all walks of life, with different backgrounds, and with a wide range of experience. A diverse and friendly community will have more great ideas, more unique perspectives, and produce more great code. We will work diligently to make the Swift community welcoming to everyone.
66

proposals/0381-task-group-discard-results.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@
55
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
66
* Status: **Implemented (Swift 5.9)**
77
* Implementation: [apple/swift#62361](https://github.com/apple/swift/pull/62361)
8-
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0381-discardingtaskgroups/62615)
8+
* Review: ([pitch](https://forums.swift.org/t/pitch-task-pools/61703)) ([review](https://forums.swift.org/t/se-0381-discardresults-for-taskgroups/62072)) ([acceptance](https://forums.swift.org/t/accepted-se-0381-discardingtaskgroups/62615))
99

1010
### Introduction
1111

1212
We propose to introduce a new type of structured concurrency task group: `Discarding[Throwing]TaskGroup`. This type of group is similar to `TaskGroup` however it discards results of its child tasks immediately. It is specialized for potentially never-ending task groups, such as top-level loops of http or other kinds of rpc servers.
1313

14-
Pitch thread: [Task Pools](https://forums.swift.org/t/pitch-task-pools/61703).
15-
1614
## Motivation
1715

1816
Task groups are the building block of structured concurrency, allowing for the Swift runtime to relate groups of tasks together. This enables powerful features such as automatic cancellation propagation, correctly propagating errors, and ensuring well-defined lifetimes, as well as providing diagnostic information to programming tools.

proposals/0414-region-based-isolation.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ point of transfer.
3232
[SE-0302](0302-concurrent-value-and-concurrent-closures.md) states
3333
that non-`Sendable` values cannot be passed across isolation boundaries. The
3434
following code demonstrates a `Sendable` violation when passing a
35-
newly-constructed value into an actor-isolated function:
35+
newly-initialized value into an actor-isolated function:
3636

3737
```swift
3838
// Not Sendable
@@ -58,9 +58,9 @@ func openNewAccount(name: String, initialBalance: Double) async {
5858

5959
This is overly conservative; the program is safe because:
6060

61-
* `client` does not have access to any non-`Sendable` state from its constructor
61+
* `client` does not have access to any non-`Sendable` state from its initializer
6262
parameters since Strings and Doubles are `Sendable`.
63-
* `client` just being constructed implies that `client` cannot have any uses
63+
* `client` just being initialized implies that `client` cannot have any uses
6464
outside of `openNewAccount`.
6565
* `client` is not used within `openNewAccount` beyond `addClient`.
6666

@@ -223,7 +223,7 @@ precise regions.
223223

224224
Now lets apply these rules to some specific examples in Swift code:
225225

226-
* **Initializing a let or var binding**. ``let y = x, var y = x``. Initializing
226+
* **Initializing a `let` or `var` binding**. ``let y = x, var y = x``. Initializing
227227
a let or var binding `y` with `x` results in `y` being in the same region as
228228
`x`. This follows from rule `(2)` since formally a copy is equivalent to calling a
229229
function that accepts `x` and returns a copy of `x`.
@@ -243,7 +243,7 @@ Now lets apply these rules to some specific examples in Swift code:
243243
change program semantics. A valid program must still obey the no-reuse
244244
constraints of `consume`.
245245

246-
* **Assigning a var binding**. ``y = x``. Assigning a var binding `y` with `x`
246+
* **Assigning a `var` binding**. ``y = x``. Assigning a var binding `y` with `x`
247247
results in `y` being in the same region as `x`. If `y` is not captured by
248248
reference in a closure, then `y`'s previous assigned region is forgotten due
249249
to `(3)(b)`:
@@ -1723,9 +1723,9 @@ resulting in a race against a write in the closure.
17231723
## Source compatibility
17241724

17251725
Region-based isolation opens up a new data-race safety hole when using APIs
1726-
change the static isolation in the implementation of a `nonisolated` funciton,
1726+
change the static isolation in the implementation of a `nonisolated` function,
17271727
such as `assumeIsolated`, because values can become referenced by actor-isolated
1728-
state without any indication in the funciton signature:
1728+
state without any indication in the function signature:
17291729

17301730
```swift
17311731
class NonSendable {}
@@ -1887,7 +1887,7 @@ func example(_ x: NonSendable) async -> NonSendable? {
18871887
}
18881888
```
18891889

1890-
In the above, the result of `example` is a newly constructed value that has no
1890+
In the above, the result of `example` is a newly initialized value that has no
18911891
data dependence on the parameter `x`, but as laid out in this proposal, we
18921892
cannot express this. We propose the addition of a new function parameter
18931893
modifier called `returnsIsolated` that causes callers to treat the result of a
@@ -2034,7 +2034,7 @@ also be ascertained by just reading the source.
20342034

20352035
## Acknowledgments
20362036

2037-
This proposal is based on work from the PLDI 2022 paper (A Flexible Type System for Fearless Concurrency)[https://www.cs.cornell.edu/andru/papers/gallifrey-types/].
2037+
This proposal is based on work from the PLDI 2022 paper [A Flexible Type System for Fearless Concurrency](https://www.cs.cornell.edu/andru/papers/gallifrey-types/).
20382038

20392039
Thanks to Doug Gregor, Kavon Farvardin for early assistance to Joshua during his
20402040
internship.

proposals/0424-custom-isolation-checking-for-serialexecutor.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ The following example demonstrates such a situation:
2222
import Dispatch
2323

2424
actor Caplin {
25-
let queue: DispatchSerialQueue(label: "CoolQueue")
25+
let queue: DispatchSerialQueue = .init(label: "CoolQueue")
2626

2727
var num: Int // actor isolated state
2828

@@ -35,9 +35,9 @@ actor Caplin {
3535
queue.async {
3636
// guaranteed to execute on `queue`
3737
// which is the same as self's serial executor
38-
queue.assertIsolated() // CRASH: Incorrect actor executor assumption
39-
self.assumeIsolated { // CRASH: Incorrect actor executor assumption
40-
num += 1
38+
self.queue.assertIsolated() // CRASH: Incorrect actor executor assumption
39+
self.assumeIsolated { caplin in // CRASH: Incorrect actor executor assumption
40+
caplin.num += 1
4141
}
4242
}
4343
}
@@ -132,7 +132,7 @@ Specific use-cases of this API include `DispatchSerialQueue`, which would be abl
132132
// Dispatch
133133

134134
extension DispatchSerialQueue {
135-
public func checkIsolated(message: String) {
135+
public func checkIsolated() {
136136
dispatchPrecondition(condition: .onQueue(self)) // existing Dispatch API
137137
}
138138
}
@@ -191,7 +191,7 @@ The custom heurystics that are today part of the Swift Concurrency runtime to de
191191
```swift
192192
// concurrency runtime pseudo-code
193193
if expectedExecutor.isMainActor() {
194-
expectedExecutor.checkIsolated(message: message)
194+
expectedExecutor.checkIsolated()
195195
}
196196
```
197197

proposals/0430-transferring-parameters-and-results.md

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
* Proposal: [SE-0430](0430-transferring-parameters-and-results.md)
44
* Authors: [Michael Gottesman](https://github.com/gottesmm), [Holly Borla](https://github.com/hborla), [John McCall](https://github.com/rjmccall)
55
* Review Manager: [Becca Royal-Gordon](https://github.com/beccadax)
6-
* Status: **Implemented (Swift 6.0)**
6+
* Status: **Active Review (June 21 ... 28, 2024)**
7+
* Implementation: Implemented in Swift 6.0 except for amendment under review
78
* Previous Proposal: [SE-0414: Region-based isolation](/proposals/0414-region-based-isolation.md)
8-
* Review: ([pitch](https://forums.swift.org/t/pitch-transferring-isolation-regions-of-parameter-and-result-values/70240)) ([first review](https://forums.swift.org/t/se-0430-transferring-isolation-regions-of-parameter-and-result-values/70830)) ([returned for revision](https://forums.swift.org/t/returned-for-revision-se-0430-transferring-isolation-regions-of-parameter-and-result-values/71297)) ([second review](https://forums.swift.org/t/se-0430-second-review-sendable-parameter-and-result-values/71685)) ([acceptance with modifications](https://forums.swift.org/t/accepted-with-modifications-se-0430-second-review-sendable-parameter-and-result-values/71850))
9+
* Previous Revisions: [1](https://github.com/apple/swift-evolution/blob/87943205551af43682ef50260816f3ff2ef9b7ea/proposals/0430-transferring-parameters-and-results.md) [2](https://github.com/apple/swift-evolution/blob/4dded8ed382b526a5a301c225a1d45018f8d556b/proposals/0430-transferring-parameters-and-results.md)
10+
* Review: ([pitch](https://forums.swift.org/t/pitch-transferring-isolation-regions-of-parameter-and-result-values/70240)) ([first review](https://forums.swift.org/t/se-0430-transferring-isolation-regions-of-parameter-and-result-values/70830)) ([returned for revision](https://forums.swift.org/t/returned-for-revision-se-0430-transferring-isolation-regions-of-parameter-and-result-values/71297)) ([second review](https://forums.swift.org/t/se-0430-second-review-sendable-parameter-and-result-values/71685)) ([acceptance with modifications](https://forums.swift.org/t/accepted-with-modifications-se-0430-second-review-sendable-parameter-and-result-values/71850)) ([amendment pitch](https://forums.swift.org/t/pitch-revise-se-0430-to-adopt-sending-on-unsafecontinuation/72289)) ([amendment review](https://forums.swift.org/t/amendment-se-0430-sending-parameter-and-result-values/72653))
911

1012

1113
## Introduction
@@ -370,12 +372,12 @@ struct Y2: P1 {
370372
}
371373
```
372374

373-
### `sending inout` parameters
375+
### `inout sending` parameters
374376

375377
A `sending` parameter can also be marked as `inout`, meaning that the argument
376378
value must be in a disconnected region when passed to the function, and the
377379
parameter value must be in a disconnected region when the function
378-
returns. Inside the function, the `sending inout` parameter can be merged with
380+
returns. Inside the function, the `inout sending` parameter can be merged with
379381
actor-isolated callees or further sent as long as the parameter is
380382
re-assigned a value in a disconnected region upon function exit.
381383

@@ -404,17 +406,15 @@ so there is no way to change the default ownership convention of a
404406
### Adoption in the Concurrency library
405407

406408
There are several APIs in the concurrency library that send a parameter across
407-
isolation boundaries and don't need the full guarnatees of `Sendable`. These
409+
isolation boundaries and don't need the full guarantees of `Sendable`. These
408410
APIs will instead adopt `sending` parameters:
409411

410412
* `CheckedContinuation.resume(returning:)`
413+
* `UnsafeContinuation.resume(returning:)`
411414
* `Async{Throwing}Stream.Continuation.yield(_:)`
412415
* `Async{Throwing}Stream.Continuation.yield(with:)`
413416
* The `Task` creation APIs
414417

415-
Note that this list does not include `UnsafeContinuation.resume(returning:)`,
416-
because `UnsafeContinuation` deliberately opts out of correctness checking.
417-
418418
## Source compatibility
419419

420420
In the Swift 5 language mode, `sending` diagnostics are suppressed under
@@ -481,3 +481,66 @@ It was also suggested that perhaps instead of renaming `transferring` to
481481
authors since it runs into the same problem as `transferring` namely that it is
482482
suggesting that the value is actively being moved to another isolation domain,
483483
when we are expressing a latent capability of the value.
484+
485+
### Exclude `UnsafeContinuation`
486+
487+
An earlier version of this proposal excluded
488+
`UnsafeContinuation.resume(returning:)` from the list of standard library
489+
APIs that adopt `sending`. This meant that `UnsafeContinuation` didn't
490+
require either the return type to be `Sendable` or the return value to be
491+
`sending`. Since `UnsafeContinuation` is unconditionally `Sendable`, this
492+
effectively made it a major hole in sendability checking.
493+
494+
This was an intentional choice. The reasoning was that `UnsafeContinuation`
495+
was already an explicitly unsafe type, and so it's not illogical for it
496+
to also work as an unsafe opt-out from sendability checks. There are some
497+
uses of continuations that do need an opt-out like this. For example, it
498+
is not uncommon for a continuation to be resumed from a context that's
499+
isolated to the same actor as the context that called `withUnsafeContinuation`.
500+
In this situation, the data flow through the continuation is essentially
501+
internal to the actor. This means there's no need for any sendability
502+
restrictions; both `sending` and `Sendable` would be over-conservative.
503+
504+
However, the nature of the unsafety introduced by this exclusion is very
505+
different from the normal unsafety of an `UnsafeContinuation`.
506+
Continuations must be resumed exactly once; that's the condition that
507+
`CheckedContinuation` checks. If a programmer can prove that
508+
they will do that to their own satisfaction, they should be able to use
509+
`UnsafeContinuation` instead of `CheckedContinuation` in full confidence.
510+
Making `UnsafeContinuation` *also* a potential source of concurrency-safety
511+
holes is likely to be surprising to programmers.
512+
513+
Conversely, if a programmer needs to opt out of sendability checks but
514+
is *not* confident about how many times their continuation will be
515+
resumed --- for example, if it's resumed from an arbitrary callback ---
516+
forcing them to adopt `UnsafeContinuation` in order to achieve their
517+
goal is actively undesirable.
518+
519+
Not requiring `sending` in `UnsafeContinuation` also makes the high-level
520+
interfaces of `UnsafeContinuation` and `CheckedContinuation` inconsistent.
521+
This means that programmers cannot always easily move from an unsafe to a
522+
checked continuation. That is a common need, for example when fixing
523+
a bug and trying to prove that the unsafe continuation is not implicated.
524+
525+
Swift has generally resisted adding new dimensions of unsafety to unsafe
526+
types this way. For example, `UnsafePointer` was originally specified as
527+
unconditionally `Sendable` in [SE-0302][], but that conformance was
528+
removed in [SE-0331][], and pointers are now unconditionally
529+
non-`Sendable`. The logic in both of those proposals closely parallels
530+
this one: at first, `UnsafePointer` was seen as an unsafe type that should
531+
not be burdened with partial safety checks, and then the community
532+
recognized that this was actually adding a new dimension of unsafety to
533+
how the type interacted with concurrency.
534+
535+
Finally, there is already a general unsafe opt-out from sendability
536+
checking: `nonisolated(unsafe)`. It is better for Swift to encourage
537+
consistent use of a single unsafe opt-out than to build *ad hoc*
538+
opt-outs into many different APIs, because it is much easier to find,
539+
recognize, and audit uses of the former.
540+
541+
For these reasons, `UnsafeContinuation.resume(returning:)` now requires
542+
its argument to be `sending`, and the result of `withUnsafeContinuation`
543+
is correspondingly now marked as `sending`.
544+
545+
[SE-0302]: https://github.com/apple/swift-evolution/blob/main/proposals/0302-concurrent-value-and-concurrent-closures.md
546+
[SE-0331]: https://github.com/apple/swift-evolution/blob/main/proposals/0331-remove-sendable-from-unsafepointer.md

proposals/0434-global-actor-isolated-types-usability.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Review Manager: [John McCall](https://github.com/rjmccall)
66
* Status: **Implemented (Swift 6.0)**
77
* Upcoming Feature Flag: `GlobalActorIsolatedTypesUsability`
8-
* Review: ([pitch](https://forums.swift.org/t/pitch-usability-of-global-actor-isolated-types/70799)) ([review](https://forums.swift.org/t/se-0434-usability-of-global-actor-isolated-types/71187))
8+
* Review: ([pitch](https://forums.swift.org/t/pitch-usability-of-global-actor-isolated-types/70799)) ([review](https://forums.swift.org/t/se-0434-usability-of-global-actor-isolated-types/71187)) ([acceptance](https://forums.swift.org/t/accepted-se-0434-usability-of-global-actor-isolated-types/72743))
99

1010
## Introduction
1111

@@ -248,6 +248,10 @@ An alternative choice would be to introduce an upcoming feature flag that's enab
248248

249249
The existing adoption implications of `@Sendable` and global actor isolation adoption apply when making use of the rules in this proposal. For example, `@Sendable` and `@MainActor` can be staged into existing APIs using `@preconcurrency`. See [SE-0337: Incremental migration to concurrency checking](/proposals/0337-support-incremental-migration-to-concurrency-checking.md) for more information.
250250

251+
## Alternatives considered
252+
253+
Instead of implicitly suppressing a `Sendable` conformance on isolated subclasses of non-`Sendable`, non-isolated superclasses, the compiler could instead require an explicit opt-out, such as `~Sendable` in the conformance clause. This would make it obvious that the subclass does not have a `Sendable` conformance. However, the programmer does not need to understand that the class does not conform to `Sendable` until they use the type in a way that requires `Sendable`, and the reason for the class not conforming to `Sendable` can be explained with notes attached to the diagnostic. It is also not always the case that global actor isolation implies `Sendable`. Notably, `@MainActor` on a protocol does not imply that the protocol refines `Sendable`, so requiring more boilerplate for programmers in the isolated subclass case does not leave the programmer with a simple rule to remember about when `@MainActor` implies a conformance to `Sendable`.
254+
251255
## Acknowledgments
252256

253257
Thank you to Frederick Kellison-Linn for surfacing the problem with global-actor-isolated function types, and to Kabir Oberai for exploring the implications more deeply.

0 commit comments

Comments
 (0)