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-9446] Higher order functions accepts arguments with invalid type #51910

Closed
jepers opened this issue Dec 8, 2018 · 2 comments
Closed

[SR-9446] Higher order functions accepts arguments with invalid type #51910

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

Comments

@jepers
Copy link

jepers commented Dec 8, 2018

Previous ID SR-9446
Radar None
Original Reporter @jepers
Type Bug
Status Closed
Resolution Invalid
Environment

Xcode 10.1 default toolchain and dev snapshot 2018-12-06

Additional Detail from JIRA
Votes 0
Component/s
Labels Bug
Assignee None
Priority Medium

md5: 3862c9fc9fd0e37c09b1a1ceccc19f38

Issue Description:

More details here.

typealias TwoIntsFn = (_ a: Int, _ b: Int) -> Int
typealias IntPairFn = (_ pair: (Int, Int)) -> Int

func twoIntsFn(_ a: Int, _ b: Int) -> Int { return a + b }
func intPairFn(_ pair: (Int, Int)) -> Int { return pair.0 + pair.1 }

func takesTwoIntsFn(_ twoIntsFn: TwoIntsFn) { print("Two-ints-function!") }
func takesIntPairFn(_ intPairFn: IntPairFn) { print("Int-pair-function!") }

func test() {
    
    let _: TwoIntsFn = twoIntsFn // OK (as expected)
    let _: IntPairFn = intPairFn // OK (as expected)

    //let _: TwoIntsFn = intPairFn // ERROR 1 (as expected)
    //let _: IntPairFn = twoIntsFn // ERROR 2 (as expected)

    takesTwoIntsFn(twoIntsFn) // OK, prints "Two-ints-function!" (as expected)
    takesIntPairFn(intPairFn) // OK, prints "Int-pair-function!" (as expected)

    // BUT, the following also compiles, even though arguments of the wrong
    // type is given. So these should be errors just like ERROR 1 and 2 above:
    takesTwoIntsFn(intPairFn) // Prints "Two-ints-function!" (should be error)
    takesIntPairFn(twoIntsFn) // Prints "Int-pair-function!" (should be error)
}
test()
@slavapestov
Copy link
Member

If you dig through the old discussion about SE-0110, takesIntPairFn(twoIntsFn) is expected to work. This was the compromise solution that was introduced in response to feedback about common idioms such as calling "map" on a dictionary and passing in a closure taking two parameters not working.

"takesIntPairFn(twoIntsFn)" also worked in Swift 4.0, before the FunctionType representation began to properly model parameters. This was an oversight. If you try a recent development snapshot, you'll notice that -swift-version 5 rejects this call:

bbb.swift:23:20: error: cannot convert value of type '((Int, Int)) -> Int' to expected argument type '(Int, Int) -> Int'
    takesTwoIntsFn(intPairFn) // Prints "Two-ints-function!" (should be error)
                   ^~~~~~~~~

@jepers
Copy link
Author

jepers commented Dec 9, 2018

Huh, I just realized that my command line target's Swift Language Version has been set to 4.2 while I've been switching between the default toolchain and the recent master dev snapshot (which I thoughtlessly just expected to use Swift 5) ... So I got the wrong impression about the Swift 5 behavior ... Happy to see that I made a stupid mistake and things have been moving in the right direction.

@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