[Returned for Revision] SE-0364: Warning for Retroactive Conformance of External Types

The review of SE-0364: Warning for Retroactive Conformance of External Types ran from July 13th to 27th. The language workgroup has decided to accept in principle that a warning should be added for such conformances, but we are returning the proposal for revision to explore what the mechanism of silencing the warning should be.

Accepted principles
Some reviewers felt that no change was warranted, as retroactive conformances are an essential tool in the language, but the workgroup believes that the sometimes-subtle distinction between normal and retroactive conformances merits some special attention from the developer, and therefore requiring a source annotation is appropriate.

Some reviewers advocated for removing retroactive conformances entirely in a future version. This is a step too far, as they are necessary to resolve some problems developers face without undue burden.

Request for revised proposal
The proposed mechanism for silencing the warning is to fully-qualify both the type and protocol names in the conformance:

extension SomeModule.Type: SomeOtherModule.Protocol { ... }

This mechanism has the desirable quality that it does not require any new language features; this is a valid conformance in Swift 5.7, and would continue to be a valid conformance in the future. However, during the review period several commenters noted that they would prefer a more heavyweight indication that a conformance is retroactive. In returning for revision, we would like to consider the following alternative mechanism for silencing the warning:

extension Type: @retroactive Protocol { ... }

There are several considerations that might make this a desirable alternative:

  • it is visual distinct, and easy to search for.
  • there is existing support for @unchecked Sendable, so we are not blazing new syntactic or conceptual ground.
  • although all conformances are treated the same by the runtime at present, the information that a conformance is retroactive is available to the runtime. Thus, a future version might give retroactive conformances different semantics in casts in an attempt to resolve some of the issues that are raised in the thread for this proposal. In light of this, giving such conformances a visibly distinct (and searchable) source-level syntax may be appropriate.

There are also some concerns with this approach: it is an entire attribute devoted to silence one warning, which additionally isn't currently valid Swift and therefore requires expanded #if support for ergonomic reasons. Thus, we would also want to support module-qualification for at least one Swift release.

Thank you for participating in Swift Evolution.

16 Likes

Hi folks!

After only [checks watch] uh, 6 months, I've finally updated this PR to include the new @retroactive Protocol syntax (with module-qualification as a fallback still).

It also includes errors to enforce that @retroactive is only ever used in an extension that's creating a retroactive conformance. If we find any other uses for @retroactive, then we can relax this rule, but I prefer keeping it as an error.

The PR has been updated at Warn when an extension declares a retroactive conformance by harlanhaskins · Pull Request #36068 · apple/swift · GitHub

And the proposal has been updated at Update SE-0364 to new @retroactive syntax by harlanhaskins · Pull Request #1969 · apple/swift-evolution · GitHub

10 Likes

For the record, I think this is a good use of an @ attribute. It provides the compiler with meta-information about your use of a language feature.

3 Likes