imre
imre

Reputation: 1717

Swift: Why is this call ambiguous?

Why does the following code yield an "Ambiguous use of 'foo'" compile error? I'd think that the return value makes it clear which one of the foo() overloads should be called.

Even more interestingly, why does the error disappear if I remove the print("x") line? What difference does that make?

(Xcode 10.2.1, Swift 5, default build settings for a new project.)

func foo(_: () -> Int) {}
func foo(_: () -> String) {}

func bar() {
    foo() {
        print("x")
        return 42
    }
}

Upvotes: 0

Views: 172

Answers (1)

Jack Lawrence
Jack Lawrence

Reputation: 10772

Type inference only applies to single-expression closures, so the compiler doesn't attempt to infer the type of the closure based on the return expression because there are two expressions (the print and the return). It then tries to infer the return type based on the return type of the closure passed to foo, but it finds two different foos and can't decide which one to use, so it then complains of an ambiguous use of foo. If you explicitly declare the type of the closure, the following code will compile:

func bar() {
    foo() { () -> Int in
        print("x")
        return 42
    }
}

Upvotes: 4

Related Questions