How to use @retroactive when the conformed protocol is a customized protocol inherited from `CustomStringConvertible`

Here's an example

public protocol MyProtocol : CustomStringConvertible {
    // Some attributes
}

extension MyProtocol {
    public var description : String{
        // Implementation
    }
}

extension SomeImportedStruct: MyProtocol {}

It gives an error:
Extension declares a conformance of imported type 'SomeImportedStruct' to imported protocol 'CustomStringConvertible'; this will not behave correctly if the owners of 'SomeImportedModule' introduce this conformance in the future.

If I add @retroactive like this:

extension SomeImportedStruct: @retroactive MyProtocol {}

It gives an error:
'retroactive' attribute does not apply; 'MyProtocol' is declared in this module; this is an error in the Swift 6 language mode.

How to use @retroactive to fix this scenario? I guess I can wrap it using a new struct or not making MyProtocol conform to CustomStringConvertible, but I think there should be some simple solution like

public protocol MyProtocol : @retroactive CustomStringConvertible {

to tell the compiler when checking conformance of MyProtocol, don't complain about CustomStringConvertible?
(Currently it's not allowed: 'retroactive' attribute only applies in inheritance clauses in extensions)

1 Like

Good catch! You can check if this issue has already been reported at Issues · swiftlang/swift · GitHub, and create a new one otherwise.

Does using two extensions work?

extension SomeImportedStruct: @retroactive CustomStringConvertible { 
    var description: String { ... }
}

extension SomeImportedStruct: MyProtocol { }

Ah yes, this surely fixes my problem!

But I'm also curious if I'm a library's author, and in my library I have a MyProtocol that conforms to something like CustomStringConvertible, and other users use this MyProtocol in their code. Isn't that causing some problems since it requires users to modify their code to conform to CustomStringConvertible using @retroactive mark, and I as a library author cannot fix their problem because I don't have control over users' code?

Of course it should not be a big problem (not really hard to fix). I just think it might be more convenient if I (as the library's author) can just do
public protocol MyProtocol : @retroactive CustomStringConvertible { so users just need to upgrade the swift package?

The conformance would be retroactive only if your end user doesn't own the type they're conforming, in which case both the CustomStringConvertible and MyProtocol conformance would be retroactive (they neither own CustomStringConvertible—it is defined in the standard library—nor MyProtocol—it is defined in your library and not your end users' code). So your end user would have to use @retroactive no matter what.

3 Likes