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-10007] Casting error with tuples #52410

Open
swift-ci opened this issue Feb 27, 2019 · 1 comment
Open

[SR-10007] Casting error with tuples #52410

swift-ci opened this issue Feb 27, 2019 · 1 comment

Comments

@swift-ci
Copy link
Collaborator

@swift-ci swift-ci commented Feb 27, 2019

Previous ID SR-10007
Radar None
Original Reporter Tainnor (JIRA User)
Type Bug
Environment

Apple Swift version 4.2.1 (swiftlang-1000.11.42 clang-1000.11.45.1)
Target: x86_64-apple-darwin18.2.0

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, RunTimeCrash, Runtime, SILGen
Assignee None
Priority Medium

md5: b136ffa2ceaa3e278adf2b4bdf1b810d

Issue Description:

The following code compiles fine but throws an unhelpful runtime error:

private func liftToEnumerated<A1, A2, B>(_ f: @escaping (A1, A2) -> B) -> ((Int, A1), (Int, A2)) -> B {
    return { enumerated1, enumerated2 in f(enumerated1.1, enumerated2.1) }
}

private func liftAllToEnumerated<A1, A2, B>(_ fs: [(A1, A2) -> B]) -> [((Int, A1), (Int, A2)) -> B] {
    return fs.map(liftToEnumerated)
}

extension Sequence {
    func sorted(byMultiple predicates: [(Element, Element) -> Bool]) -> [Self.Element] {
        let combinedPredicate = { (e1: Element, e2: Element) -> Bool in
            return predicates.reduce(false) { areInIncreasingOrder, predicate in
                return areInIncreasingOrder || predicate(e1, e2)
            }
        }

        return sorted(by: combinedPredicate)
    }
}

let ps: [(Int, Int) -> Bool] = [{_, _ in true}]
// this is fine:
[1,2,3].sorted(byMultiple: ps)
// this crashes:
[1,2,3].enumerated().sorted(byMultiple: liftAllToEnumerated(ps))

The error message is (in the REPL, but it also crashes outside of the REPL):

Could not cast value of type '((Swift.Int, Swift.Int), (Swift.Int, Swift.Int)) -> Swift.Bool' (0x1013d29b8) to '((offset: Swift.Int, element: Swift.Int), (offset: Swift.Int, element: Swift.Int)) -> Swift.Bool' (0x1013d2cc0).
2019-02-27 16:42:18.871464+0100 repl_swift[65408:923280] Could not cast value of type '((Swift.Int, Swift.Int), (Swift.Int, Swift.Int)) -> Swift.Bool' (0x1013d29b8) to '((offset: Swift.Int, element: Swift.Int), (offset: Swift.Int, element: Swift.Int)) -> Swift.Bool' (0x1013d2cc0).
Execution interrupted. Enter code to recover and continue.
Enter LLDB commands to investigate (type :help for assistance.)
Process 65408 stopped
* thread #&#8203;1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #&#8203;0: 0x00007fff7879623e libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff7879623e <+10>: jae    0x7fff78796248            ; <+20>
    0x7fff78796240 <+12>: movq   %rax, %rdi
    0x7fff78796243 <+15>: jmp    0x7fff787903b7            ; cerror_nocancel
    0x7fff78796248 <+20>: retq
Target 0: (repl_swift) stopped.

I don't really understand what's going on here.

@belkadan
Copy link
Contributor

@belkadan belkadan commented Feb 27, 2019

The compiler's inserting a cast that removes tuple labels from within a function type, but the runtime doesn't know how to do that. I think your code is valid but it's certainly relying on that; you could match the return type of enumerated() to not rely on that:

private func liftToEnumerated<A1, A2, B>(_ f: @escaping (A1, A2) -> B) -> ((offset: Int, element: A1), (offset: Int, element: A2)) -> B {
    return { enumerated1, enumerated2 in f(enumerated1.1, enumerated2.1) }
}

private func liftAllToEnumerated<A1, A2, B>(_ fs: [(A1, A2) -> B]) -> [((offset: Int, element: A1), (offset: Int, element: A2)) -> B] {
    return fs.map(liftToEnumerated)
}

cc @xedin, @slavapestov

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants