Skip to content

Conversation

@DougGregor
Copy link
Member

@DougGregor DougGregor commented Aug 8, 2024

Within Swift 6.0, we expanded an optimization for witness tables that that allowed direct access to the witness table for conformances to any protocol that can never have a witness table, rather than requiring access through swift_getWitnessTable that might need to instantiate the witness table.

The previous optimization only covered Objective-C protocols, but Swift 6.0 expanded that to marker protocols (such as Sendable) as well.

However, this constituted an ABI break when a Swift 6.0 compiler uses a witness table that comes from a library built with an earlier version of Swift, when the protocol inherits from Sendable but the conformance to that protocol otherwise does not require an instantiation function. In such cases, Swift 6.0 would generate code that directly accesses the uninstantiated witness table symbol, which will have NULL entries for any conformance in it that was considered "dependent" by the earlier Swift compiler.

Introduce a deployment target check to guard the new optimization. Specifically, when building for a deployment target that predates Swift 6.0, treat conformances to marker protocols as if they might be dependent (so the access patterns go through swift_getWitnessTable for potential instantiation on older platforms). For newer deployment targets, use the more efficent direct access pattern.

Fixes rdar://133157093, fixes #75155

…r-dependent

Within Swift 6.0, we expanded an optimization for witness tables that
that allowed direct access to the witness table for conformances to
any protocol that can never have a witness table, rather than requiring
access through `swift_getWitnessTable` that might need to instantiate
the witness table.

The previous optimization only covered Objective-C protocols, but Swift
6.0 expanded that to marker protocols (such as `Sendable`) as well.

However, this constituted an API break when a Swift 6.0 compiler uses
a witness table that comes from a library built with an earlier version
of Swift, when the protocol inherits from Sendable but the conformance
to that protocol otherwise does not require an instantiation function.
In such cases, Swift 6.0 would generate code that directly accesses
the uninstantiated witness table symbol, which will have NULL entries
for any conformance in it that was considered "dependent" by the
earlier Swift compiler.

Introduce a deployment target check to guard the new optimization.
Specifically, when building for a deployment target that predates
Swift 6.0, treat conformances to marker protocols as if they might be
dependent (so the access patterns go through `swift_getWitnessTable`
for potential instantiation on older platforms). For newer deployment
targets, use the more efficent direct access pattern.

Fixes rdar://133157093.
@DougGregor DougGregor requested a review from rjmccall as a code owner August 8, 2024 05:06
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor DougGregor merged commit ae71175 into swiftlang:main Aug 8, 2024
@DougGregor DougGregor deleted the deployment-gate-nondependent-marker-conformances branch August 8, 2024 17:54
DougGregor added a commit to DougGregor/swift that referenced this pull request Sep 10, 2024
… targets

A change to the way we determined whether a protocol conformance is
"dependent" for marker protocols caused an ABI break for
Sendable-refining protocols built with pre-6.0 Swift compilers. The
fix for this issue (swiftlang#75769)
gated the change on deployment target.

The deployment target change fixed the original problem, then caused a
related issue when a project mixes deployment targets (pre-6.0 and
6.0+) with non-resilient protocols. Rework the logic here to (1) look at
the availability of the protocol rather than the deployment target, and
(2) always use the more efficient (non-dependent) answer for
non-resilient protocols.

Fixes rdar://134953989.
DougGregor added a commit to DougGregor/swift that referenced this pull request Sep 10, 2024
… targets

A change to the way we determined whether a protocol conformance is
"dependent" for marker protocols caused an ABI break for
Sendable-refining protocols built with pre-6.0 Swift compilers. The
fix for this issue (swiftlang#75769)
gated the change on deployment target.

The deployment target change fixed the original problem, then caused a
related issue when a project mixes deployment targets (pre-6.0 and
6.0+) with non-resilient protocols. Exempt non-resilient protocols from
this change so we get consistent behavior.

Fixes rdar://134953989.
DougGregor added a commit to DougGregor/swift that referenced this pull request Sep 10, 2024
… targets

A change to the way we determined whether a protocol conformance is
"dependent" for marker protocols caused an ABI break for
Sendable-refining protocols built with pre-6.0 Swift compilers. The
fix for this issue (swiftlang#75769)
gated the change on deployment target.

The deployment target change fixed the original problem, then caused a
related issue when a project mixes deployment targets (pre-6.0 and
6.0+) with non-resilient protocols. Exempt non-resilient protocols from
this change so we get consistent behavior.

Fixes rdar://134953989.
DougGregor added a commit that referenced this pull request Sep 11, 2024
… targets

A change to the way we determined whether a protocol conformance is
"dependent" for marker protocols caused an ABI break for
Sendable-refining protocols built with pre-6.0 Swift compilers. The
fix for this issue (#75769)
gated the change on deployment target.

The deployment target change fixed the original problem, then caused a
related issue when a project mixes deployment targets (pre-6.0 and
6.0+) with non-resilient protocols. Exempt non-resilient protocols from
this change so we get consistent behavior.

Fixes rdar://134953989.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ABI incompatibility between Swift 5 & 6 with inherited protocols

2 participants