Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-7018] Overload resolution fails for nested function #49566

Closed
jepers opened this issue Feb 17, 2018 · 2 comments
Closed

[SR-7018] Overload resolution fails for nested function #49566

jepers opened this issue Feb 17, 2018 · 2 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@jepers
Copy link

jepers commented Feb 17, 2018

Previous ID SR-7018
Radar None
Original Reporter @jepers
Type Bug
Status Closed
Resolution Invalid
Additional Detail from JIRA
Votes 0
Component/s
Labels Bug
Assignee None
Priority Medium

md5: 0aad26add04c38ffcfab162f9cd159dc

Issue Description:

The following program compiles as expected:

func f(_ x: Int) {
    print(x)
}

func f() {
    f(123) 
}

func g() {
    f(123)
}

f(123)

But note that simply moving the second f inside g produces the following (afaics) invalid compiler error for both f(123) calls:

func f(_ x: Int) {
    print(x)
}

func g() {
    func f() {
        f(123) // ERROR
    }
    f(123) // ERROR
}

f(123) // OK

// ERROR = Argument passed to call that takes no arguments

The following program demonstrates that even though the two f-functions have a different number of parameters and different argument labels, the compiler still fails to see that it is the outer f(number: ) that is being called:

func f(number x: Int) {
    print(x)
}

func g() {
    func f(string: String, arrayOfStrings: [String]) {
        f(number: 123) // ERROR
    }
    f(number: 123) // ERROR
}

f(number: 123) // OK

// ERROR = Missing argument for parameter 'arrayOfString' in call

(As before, moving the inner f(string: arrayOfStrings: ) out of g() will make it compile successfully.)

And a final one that demonstrates an other invalid error that is produced when the outer f is called before the declaration of the inner f:

func f() {
    print("Hi! I'm the only f that is being called in this (valid) program.")
}

func g() {
    f() // ERR: Use of local variable `f` before its declaration
    func f(compilerBug invalidError: String) {
        f() // ERR: Missing argument parameter for parameter `compilerBug` in call 
    }
    f() // ERR: Missing argument parameter for parameter `compilerBug` in call
}

f()

I've reproduced the issue(s) using in Xcode 9.3 beta 2 with both default toolchain and latest development snapshot.

@belkadan
Copy link
Contributor

This is behaving as designed, although people have complained about it before. Overload resolution works on a set of functions in the same context, so in this case once the nested function is found the compiler stops looking for other overloads. You can always use MyModule.f to reference the top-level function.

@jepers
Copy link
Author

jepers commented Feb 20, 2018

Oh, ok, thanks! I can understand it after your explanation but I still think it's unintuitive, especially when for example the following compiles fine:

func f() {
    print("The f in global scope!")
}

func g() {
    func f() {
        print("The f nested in g!")
    }
    f()
}
f() // The f in global scope!
g() // The f nested in g!

Meaning it's OK to shadow functions, but when trying to overload and call the outer f, you get very strange diagnostics (see last example program in the report that is kind of similar to this).

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.
Projects
None yet
Development

No branches or pull requests

2 participants