Commits

Doug Gregor committed 58570fdf9a6
Introduce "near-miss" warnings for unsatisfied optional requirements. It's a common mistake to mistype a declaration that is intended to satisfy an optional requirement. In such "near misses", we want to warn about the mistake and give the user options to either fix the declaration or suppress the warning. Approach this problem be walking over all of the members of each nominal type declaration or extension therefore and looking to see if there are any members remaining that (1) are similarly-named to an unfilfilled optional requirement of a protocol whose conformance is attributed to that nominal type declaration or extension, (2) are not witnesses to another optional requirement, (3) haven't explicitly suppressed the warning (e.g., by adding explicit "private" or explicit "@nonobjc"), and (4) have a useful suppression mechanism. In addition to the suppression mechanisms described in (3), one can suppress this warning by moving the declaration to an(other) extension. This encourages a programming style where one breaks an interface into extensions each implement conformance to one protocol. Note that we encode the various cases where one cannot move the declaration to another extension (e.g., one cannot move a designated initializer or stored property out of a class declaration) and suppress the warning when there's no way for the user to cope with it. Each warning produced by this diagnostic can have a bunch of notes on it for various courses of action. For example: t2.swift:7:14: warning: instance method 'doSomething(z:)' nearly matches optional requirement 'doSomething(x:)' of protocol 'P1' @objc func doSomething(z: Double) { } ^ t2.swift:7:14: note: rename to 'doSomething(x:)' to satisfy this requirement @objc func doSomething(z: Double) { } ^ x t2.swift:7:14: note: move 'doSomething(z:)' to an extension to silence this warning @objc func doSomething(z: Double) { } ^ t2.swift:7:14: note: make 'doSomething(z:)' private to silence this warning @objc func doSomething(z: Double) { } ^ private t2.swift:2:17: note: requirement 'doSomething(x:)' declared here optional func doSomething(x: Int) ^ It's a *lot* of detail, but is intended to cover the various choices available to the user: Fix-It to the names of the requirement (for naming-related mistakes) or suppress via various mechanisms. Combining notes means losing Fix-Its, while dropping notes can lead users to non-optimal solutions. This is more of rdar://problem/25159872.