apple / apple/swift-openapi-urlsession

Library-evolution build fails on Xcode 26.5 / Swift 6.3: `@inlinable` deinit/inits in Lock.swift require `@_fixed_layout`/`@frozen`

Open
#92 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
216
Forks
44
PR merge metrics
No merged PRs in 30d

Description

### Summary

We ship a binary **XCFramework** that bundles `OpenAPIURLSession` (used internally for REST API calls), and that XCFramework is distributed to **React Native developers** who integrate it into their apps.

Because those developers build against our prebuilt binary with their *own* (often older) Xcode/Swift toolchains, we need module stability — i.e. `BUILD_LIBRARY_FOR_DISTRIBUTION=YES` — so the framework keeps working across compiler versions. That's exactly the configuration that propagates library evolution to `OpenAPIURLSession` and trips the errors above.

Building `OpenAPIURLSession` with library evolution enabled (`-enable-library-evolution` / `BUILD_LIBRARY_FOR_DISTRIBUTION=YES`) fails to compile on **Xcode 26.5 / Swift 6.3**. This happens when the package is a (transitive) dependency of a framework that is archived for binary distribution as an XCFramework. The same configuration compiled on earlier toolchains, so this is a regression triggered by the newer compiler's stricter enforcement.

### Environment

- Xcode 26.5 (build 17F42)
- Apple Swift 6.3.2 (swiftlang-6.3.2.1.108, clang-2100.1.1.101)
- `swift-openapi-urlsession` `main` (the constructs below are present in all 1.0.0–1.3.0 releases)

### Errors

```
Sources/OpenAPIURLSession/BufferedStream/Lock.swift:190:5: error: deinitializer can only be '@inlinable' if the class is '@_fixed_layout'
Sources/OpenAPIURLSession/BufferedStream/Lock.swift:244:14: error: 'let' property '_storage' may not be initialized directly; use "self.init(...)" or "self = ..." instead
Sources/OpenAPIURLSession/BufferedStream/Lock.swift:322:14: error: 'let' property '_storage' may not be initialized directly; use "self.init(...)" or "self = ..." instead
```

### Reproduction

```bash
swift build -Xswiftc -enable-library-evolution
```

### Cause

In `Sources/OpenAPIURLSession/BufferedStream/Lock.swift`:

- `LockStorage` (a `final class`) declares an `@inlinable deinit`.
- `Lock` and `LockedValueBox` (structs) declare `@inlinable` initializers that directly initialize their stored `let _storage` property.

Under library evolution, types have resilient (non-fixed) layout, so the compiler requires `@_fixed_layout` (class) / `@frozen` (struct) before allowing an `@inlinable` deinit or an `@inlinable` initializer that directly assigns a stored property.

### Possible fixes

1. Mark `LockStorage` `@_fixed_layout` and `Lock` / `LockedValueBox` `@frozen` — keeps the `@inlinable` optimizations and requires no opt-in from consumers.
2. Drop `@inlinable` from those three members (negligible perf impact — a lock's deinit/init are not hot paths).

A PR follows with option (2) gated behind a compilation condition so the default build is byte-for-byte unchanged, but maintainers may prefer option (1).

Contributor guide

Open the contributing guide

Research direction

Start with Sources/OpenAPIURLSession/BufferedStream/Lock.swift and reproduce the failure using swift build -Xswiftc -enable-library-evolution. Inspect the @inlinable deinitializer and initializers for LockStorage, Lock, and LockedValueBox, then apply the maintainer-approved approach. Done means the library-evolution build succeeds on the reported Swift toolchain without changing the default build behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.