[Accepted] Amendment: SE-0364 Allow Same Package Conformances

Hi folks --

The review for an amendment to SE-0364, Allow Same Package Conformances ran from May 15 through June 17, 2024. The Language Steering Group has decided to accept the proposal.

This amendment was almost entirely uncontroversial; the only real objection came from the LSG itself, which the authors addressed by tweaking the proposal to make it so that same-package conformances are not retroactive at all. In an extended review period to consider this tweak, there was essentially no further discussion. It has taken a long time to get this proposal to completion, but I am delighted with the design that we finally landed on.

Thank you all for your feedback and patience.

10 Likes

Great improvement, thanks everyone!

Will this change be included in Swift 6.0?

If my understanding of this accepted proposal is correct, it seems that the following will trigger a warning:

// Local SPM package named Lib
public struct Feature {}
// Local SPM package named LibInterface 
public protocol FeatureAPI {}
// Local SPM package named LibOverlay
import Lib
import LibInterface
extension Feature: FeatureAPI {} // triggers warning

While the following will emit no warnings, as it is provided affordances given to modules found in the same SPM package:

// Package LibKit

// Target named Lib
public struct Feature {}
// Target named LibAPI
public protocol FeatureAPI {}
// Target named LibOverlay
import Lib
import LibAPI
extension Feature: FeatureAPI {} // no warnings here

Apologies if the above seems obvious from the proposal to some, I did in fact read it several times but am still uncertain related to the above.

The code above is and will continue to cause a compilation error:

'public' modifier cannot be used with extensions that declare protocol conformances

I've updated my post to remove the public modifier associated with the extension.

Still, I'm curious whether the new warnings will be emitted between local package boundaries, where we have user defined types in two different local packages and then provide protocol witnesses in a third local package.

Your understanding is correct, the @retroactive attribute will not be required in your second example where LibOverlay is part of the same package as Lib/LibAPI.

1 Like

Thanks a lot for confirming, I suspected as much but was not 100% certain.

Yes, it will be in 6: [6.0 🍒] [SE-0364] Relax @retroactive check to allow same-package declarations (#73512) by harlanhaskins · Pull Request #75079 · swiftlang/swift · GitHub

3 Likes

I'm excited to try out this change on the Airbnb codebase, since it will help resolve a few hundred warnings in our highly modular codebase.

Do you know when it will be included in an Xcode 16 beta release? I tested with beta 4 today but still see the warnings. I want to make sure the commit is actually included with beta 4 before I investigate further.

1 Like

The fix was not included in beta 4.

In general, the best way to be informed when a specific fix becomes available in a public Xcode release is to file a feedback with Apple. It can be a very simple report that, for example, just links to this thread and says that you want to follow the progress of the fix. We will mark it as a duplicate in our system and you will automatically get a notification when a release includes the fix.

4 Likes

Thanks! If it's helpful, the Feedback ID is FB14541163.

2 Likes

So.. does @retroactive simply silence the warning? If I use it, what happens if later that same conformance is introduced elsewhere -- ie., as the situation to which the warning was alerting?

If you’re compiling from source you’d get a compiler error. If you have a built binary like an app, you'd get a runtime issue, though I'm not sure if it's a crash or just a warning that one of the conformances will be used. So the biggest risk is for existing apps that retroactively conform system types to system protocols and the system adds the same conformance. This is extremely rare, especially since such conformances can't be back deployed (IIRC that's still true).

Is it known how to properly tell Xcode "native" targets that they belong to same "package"?

So far, I've noticed that defining same "SWIFT_PACKAGE_NAME" for all targets does seem to have same effect on this warning, making it go away. But I am unsure what other side effects this build setting has.
Example project with it: GitHub - alvarhansen/SE-0364-demo

SWIFT_PACKAGE_NAME is the correct Xcode build setting to use for this.

2 Likes