Thanks for looking into this, @Douglas_Gregor!
Another issue I have found with new rule would silently change behavior mixed with overloading:
struct Result {}
struct Either<T, U: Error> {}
struct Query {
func execute(
onCompletion: (Either<Result, Error>) -> Void,
onError: ((Error) -> Void)? = nil,
onSuccess: ((Result) -> Void)? = nil) {
print("execute 1")
}
func execute(
retries: Int = 3,
randomized: Bool = true,
onSuccess: ((Result) -> Void)? = nil) {
print("execute 2")
}
}
func test(q: Query) {
q.execute { _ in print("success!") }
}
Backward scan currently prefers second overload (Int, Bool, (Result) -> Void where forward matching (based on the toolchain) would choice the first overload and match onCompletion:.
This is something which is going to be much harder to detect and diagnose post type-check...