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-8896] Strange priorities of overloaded functions #51402

Open
swift-ci opened this issue Oct 2, 2018 · 4 comments
Open

[SR-8896] Strange priorities of overloaded functions #51402

swift-ci opened this issue Oct 2, 2018 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself feature A feature request or implementation type checker Area → compiler: Semantic analysis

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Oct 2, 2018

Previous ID SR-8896
Radar None
Original Reporter koher (JIRA User)
Type Bug
Environment

Xcode Version 10.0 (10A255)

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, LanguageFeatureRequest, TypeChecker
Assignee None
Priority Medium

md5: f29a7e269390faed1efed185be434365

Issue Description:

I think the result of the following code is strange.

class Animal {}
class Cat<T>: Animal {}

func foo(_: Animal) { print("Animal") }
func foo<T>(_: Cat<T>) { print("Cat") }

foo(Cat<Int>()) // Animal

It seems that non-generic functions are always prior to generic functions between overloads.

It is a more realistic case that `PartialKeyPath` is selected prior to `KeyPath` in the situation like below.

struct Foo {
    var x: Int = 42
    func bar(keyPath: PartialKeyPath<Foo>) { print("PartialKeyPath") }
    func bar<T>(keyPath: KeyPath<Foo, T>) { print("KeyPath") }
}

let path: KeyPath<Foo, Int> = \.x
Foo().bar(keyPath: path) // PartialKeyPath

In addition, if both of `foo` functions in the first example are generic, `Cat`'s one is selected.

func foo<X>(_: X, _: Animal) { print("Animal") }
func foo<X, T>(_: X, _: Cat<T>) { print("Cat") }

foo((), Cat<Int>()) // Cat

I think such behavior is confusing. Some languages, e.g. Kotlin, shows "Cat" for the code like the first example. Is this behavior in Swift intentional?

@belkadan
Copy link
Contributor

belkadan commented Oct 2, 2018

I think it's deliberate that non-generic functions are considered before generic ones, yes, but I can see how that's not desirable here. @rudkx, @xedin?

@xedin
Copy link
Member

xedin commented Oct 2, 2018

Yes, unfortunately this is a performance hack we have at the moment, if overload with concrete types matches, solver doesn’t consider generic ones... @rudkx is working on improving this situation.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 3, 2018

Comment by Yuta Koshizawa (JIRA)

That sounds great 🙂

@NevinBR
Copy link
Contributor

NevinBR commented Jan 26, 2020

I just ran into this today in Swift 5.1.3 with Xcode 11.3.1, when implementing a type-erasing wrapper. The result was an infinite hang because the call from the superclass into the generic subclass implementation was treated as recursive into itself instead:

class A {
  func foo(_ a: A) { fatalError() }
  func foo<U>(_ b: B<U>) { fatalError() }
}

final class B<T>: A {
  override func foo(_ a: A) { a.foo(self) }  // should call foo<U> but actually calls itself
  override func foo<U>(_ b: B<U>) { print("done") }
}

let b = B<Int>()
b.foo(b)    // endless loop

The workaround is to rename one of the functions, but that really shouldn’t be necessary because B is clearly more specific than A here.

@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
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself feature A feature request or implementation type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

4 participants