swiftxcodeprotocol-extension

Can I force the compiler to fail when some protocol functions change their signature?


Is there a way to mark some Swift functions as implementing some protocol functions so that if the protocol's signature changes, the compiler can mark implementations as an error.

For instance, consider this example where I have a default implementation of the Foo protocol for UIViewController instances, and I want to override it for a custom Bar class that is a subclass of UIViewController.

// V1
protocol Foo {
    func number() -> Int
}

extension Foo where Self: UIViewController {
    func number() -> Int {
        return 0
    } 
}

// Overrides the default implementation
extension Bar: Foo {
    func number() -> Int {
        return 1
    }
}

Now, the protocol evolves to:

// V2
protocol Foo {
    func numberV2() -> Int
}

extension Foo where Self: UIViewController {
    func numberV2() -> Int {
        return 0
    } 
}

// I think I override the default implementation but not anymore.
// => error prone, no error from the compiler
extension Bar: Foo {
    func number() -> Int {
        return 1
    }
}

How can I help my Bar extension be aware that the number function is no longer relevant for the Foo protocol?


Solution

  • No, there's currently (Swift 4.0) no way to get help from the compiler for catching these "near misses". This topic has come up several times on the swift-evolution mailing list, though, so people are definitely aware that it's a problem that should be solved.

    In fact, Doug Gregor recently made a change to the Swift compiler that will able to catch some "near misses". The change is not part of the current Swift release, but will be in Swift 4.1.

    From the mailing list post introducing the change:

    A “near-miss” warning fires when there is a protocol conformance for which:

    1) One of the requirements is satisfied by a “default” definition (e.g., one from a protocol extension), and

    2) There is a member of the same nominal type declaration (or extension declaration) that declared the conformance that has the same name as the requirement and isn’t satisfying another requirement.

    These are heuristics, of course, and we can tune the heuristics over time.

    If I understand this correctly, the current heuristics won't catch your exact issue because they only match methods with the exact same name (but differing types), but as Doug said the heuristics may be improved in the future.