AL+

Language: RO (română) EN (English)

Email us: paul@alplustech.com

Single-use Swift continuations still need a missing-resume policy

Swift's accepted continuation design prevents double resume through ownership, but callback arrival and missing-resume handling remain API design work.

Citiți articolul în română

A continuation used to bridge a callback API has two obligations: it must not resume twice, and the suspended operation needs a defined outcome if completion never arrives. Static ownership can address the first obligation without proving the second. A single-use value makes responsibility easier to assign; it cannot make an external operation call back.

That distinction should shape the adapter's API before choosing a continuation type. Success, failure and cancellation all need to fit the ownership story. So does the possibility that the callback source remains silent. An adapter is incomplete if it explains only which path resumes on success and leaves every other path to assumptions about the external component.

Acceptance and delivery are separate events

The Swift May roundup, published on 3 June 2026, discusses SE-0528 among recently accepted proposals for a future release. It describes a noncopyable Continuation that makes double resume a compile-time error and missing resume a runtime trap. This is evidence about an accepted design, not a claim about the toolchain installed in a particular project.

The acceptance announcement was posted on 6 May, after review concluded on 28 April. June's digest is a later discussion of that decision. Keeping those events separate prevents a language-design milestone from becoming an invented release date. Deployment-target replies posted in November are outside the June argument.

The practical analysis can remain useful without prescribing an immediate migration. A team can inspect ownership and failure policy in an existing adapter even when adopting a proposed API is not yet part of its delivery plan. The design question survives changes in names and availability: who is responsible for ending this suspension?

One owner is a safety property

If a continuation can be copied freely, multiple paths can hold what appears to be independent permission to complete the same suspended operation. Those paths may represent competing outcomes. A cancellation handler and a success callback, for example, may both believe they own completion. Preventing duplication removes one way to express that mistake.

The accepted noncopyable design makes ownership transfer meaningful. Passing responsibility onward consumes the previous owner's ability to use that same value. That helps explain which component may resume and gives the compiler a role in rejecting double use. The guarantee concerns the handling of the continuation value, rather than the behavior of the callback source.

An illustrative network adapter shows the remaining gap. It may transfer completion responsibility correctly to an object waiting for a response. If the external operation never produces a response and that object remains retained, the ownership story can stay coherent while the task stays suspended. Nothing about uniqueness forces the environment to make progress.

This is the difference between preventing an invalid action and proving that a required action eventually happens. An API can have exactly one owner and still need a deadline or cancellation rule. Those mechanisms must be designed around the actual external contract; a language-level uniqueness guarantee cannot supply that contract on the component's behalf.

Abandonment is a policy decision

The acceptance discussion explicitly retains runtime failure when a continuation is destroyed without resuming. That detects abandonment when destruction occurs. It does not establish a maximum waiting time for a continuation that remains alive. Treating a trap as a timeout mechanism would confuse detection of one misuse with a guarantee of eventual completion.

An adapter therefore needs a policy for each terminal outcome. If cancellation is supported, decide how it ends the suspended operation and how a later callback is handled. If the external API promises a completion callback, establish whether cancellation changes that promise. If it can remain silent, identify what event ends the wait and who owns that responsibility.

These are prerequisites for claiming that the bridge has a defined outcome on those paths. They are not a prescription to add timers to every callback. Some integrations already have a suitable lifetime contract. Others cannot impose a useful deadline without changing product behavior. The requirement is to expose the chosen policy rather than to assume that noncopyability answers it.

The same care applies to diagnostics. A runtime failure can make a programming error visible, but the product still needs to distinguish that error from an ordinary remote failure. A missing callback may be a defect in the adapter, a violated upstream promise or a condition the API deliberately permits. Each interpretation has different consequences for the caller.

CheckedContinuation can remain the practical choice

The strongest counterargument to immediate adoption is integration difficulty. The acceptance announcement expressly allows continued use of CheckedContinuation where the new type is difficult to use. That is a practical boundary on the recommendation. A more demanding ownership model can be valuable without being the easiest fit for every existing callback abstraction.

Choosing CheckedContinuation does not remove the responsibility to reason about completion. Choosing a noncopyable continuation does not remove it either. The tradeoff concerns how misuse is prevented or detected and how responsibility can be represented in the surrounding code. It should be assessed alongside compatibility, rather than treated as a ranking detached from the adapter.

For custom software development, ask for a completion contract that covers every supported exit from the external operation. Identify the owner after each transfer and the outcome when completion does not arrive. Then choose a continuation representation that supports that contract and the project's verified toolchain constraints.