Search code examples
swiftclosuresoverloadingswift3overload-resolution

Swift 3 closure overload resolution


I'm confused by function overload resolution with closures in Swift 3.

For example, in the code:

func f<T>(_ a: T) {
    print("Wide")
}

func f(_ a: (Int)->(Int)) {
    print("Narrow")
}

f({(a: Int) -> Int in return a + 1})

I expect Narrow, not Wide, to be printed to the console. Can anyone explain why the more specific overload gets chosen for non-closure arguments but not for closures or is this a compiler bug?

Swift 2 exhibited the expected behavior.


Solution

  • This is probably due to the change in the default "escaping" behaviour for closure parameters.

    If you change the specific function to:

    func f(_ a:@escaping (Int)->Int) 
    {
        print("Narrow")
    }
    

    it will print "Narrow" as expected (this is the same change that you probably had to make in several other places that were more obvious)