swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.27k stars 10.33k forks source link

[SR-1986] Unable to match the right method signature with no parameters among a set of overloaded methods #44595

Open swift-ci opened 8 years ago

swift-ci commented 8 years ago
Previous ID SR-1986
Radar None
Original Reporter zenny_chen (JIRA User)
Type Improvement
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Improvement, LanguageFeatureRequest | |Assignee | None | |Priority | Medium | md5: bca2c3a2d987d7ef76b3e678907dd235

Issue Description:

class TestClass {

    func doSomething() {
        print("do nothing")
    }

    func doSomething(a a: Int) {
        print("Param a = \(a)")
    }

    func doSomething(_ a: Int) {
        print("param = \(a)")
    }

    func doSomething(v _: Void) {
        print("do something")
    }
}

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let test = TestClass()

        // The following statement will result in an error during compilation:
        // `Ambiguous use of doSomething()`
        //let pFunc1 = test.doSomething

        let pFunc2 = test.doSomething(a:)    // OK
        let pFunc3 = test.doSomething(_:)    // OK
        let pFunc4 = test.doSomething(v:)    // OK

        pFunc2(a: 100)
        pFunc3(200)
        pFunc4(v: ())    // OK! Use an empty tuple as an argument to match type Void
    }
}

I suggest that `test.doSomething` will just provide the complete method signature for `doSomething()`. Right now, in order to solve the ambiguous method signature problem, each overloaded method has to use at least one parameter. Fortunately, an empty tuple has the type Void, so it can be used as an argument. However, the expressions such as `doSomething(v _: Void) ` and `pFunc4(v: ())` don't look so "swift".

belkadan commented 8 years ago

@DougGregor, @jckarter, did one of you have an idea in this space, or was that just #selector?

DougGregor commented 8 years ago

We could privilege the "doSomething()" syntax in #selector, but I don't think we've discussed the general issue. One can use "as" to spell the expected type of the reference.

swift-ci commented 8 years ago

Comment by Zenny Chen (JIRA)

Yes, "as" can also solve the problem.

let pFunc = test.doSomething as () -> Void

It works.

jckarter commented 8 years ago

If we required argument labels to refer to a function, that would address the ambiguity here as well, since doSomething would then only refer to the no-arguments method.

swift-ci commented 8 years ago

Comment by Zenny Chen (JIRA)

Ah yes, Joe you're right. So right now, using "as" to spell the expected type might be the best solution.

And, privileging the "doSomething()" syntax in #selector will be nice. Thanks Doug.

swift-ci commented 8 years ago

Comment by Zenny Chen (JIRA)

Excuse me, new issue here.

class TestClass {

    func doSomething() {
        print("do nothing")
    }

    func doSomething(a a: Int) {
        print("Param a = \(a)")
    }

    func doSomething(_ a: Int) {
        print("param = \(a)")
    }

    func doSomething(_ f: Float) {
        print("float = \(f)")
    }

    func doSomething(v _: Void) {
        print("do something")
    }
}

        let test = TestClass()

        // This will produce ambiguity
        //let f1 = test.doSomething as () -> Void

        // The following statements are OK
        let f2 = test.doSomething(a:)
        let f3 = test.doSomething(_:) as (Int) -> Void
        let f4 = test.doSomething(_:) as (Float) -> Void
        let f5 = test.doSomething(v:)

Now, the problem is that the method cannot be distinguished between with argument label and without argument labels – doSomething() and doSomething(v🙂

jckarter commented 8 years ago

Yeah, I think you need the combination of required labels in function references and type context to be able to unambiguously refer to any overload we support.

swift-ci commented 8 years ago

Comment by Zenny Chen (JIRA)

Yes Joe, that's it! 🙂