Skip to content

Don't report functions that conform to a protocol as unused if removing them would break the build #1059

@danwood

Description

@danwood

Describe the bug

Periphery incorrectly marks methods as unused when they are required protocol conformance implementations. Removing these methods would break the build since the type would no longer conform to the protocol.

Reproduction

Given a protocol:

protocol DocumentRenamable {
    func canRename(in context: NSManagedObjectContext) -> Bool
    func currentName() -> String
    func applyRename(_ newName: String)
}

And a conforming extension:

extension Note: DocumentRenamable {
    func canRename(in context: NSManagedObjectContext) -> Bool { true }

    func currentName() -> String {
        // implementation
    }

    func applyRename(_ newName: String) {
        // implementation
    }
}

Periphery reports all three methods as unused, which is technically true!

Note+Renamable.swift:5:10: warning: Function 'canRename(in:)' is unused
Note+Renamable.swift:7:10: warning: Function 'currentName()' is unused
Note+Renamable.swift:12:10: warning: Function 'applyRename(_:)' is unused

The DocumentRenamable protocol is used elsewhere in the codebase, so that’s definitely in use. Following Periphery's suggestion to remove these methods would leave an empty extension Note: DocumentRenamable { } which fails to compile because Note no longer satisfies the protocol requirements.

Expected behavior

Periphery should check whether a method flagged as unused is required by a protocol the type conforms to. Methods that satisfy protocol requirements should not be marked as unused, since removing them would break the build.

Environment

3.4.0
swift-driver version: 1.127.14.1 Apple Swift version 6.2.3 (swiftlang-6.2.3.3.21 clang-1700.6.3.2)
Target: arm64-apple-macosx26.0
Xcode 26.2
Build version 17C52

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions