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-13657] Ambiguous use of function when used within a namespace or as an instance method #56092

Open
swift-ci opened this issue Oct 5, 2020 · 7 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Oct 5, 2020

Previous ID SR-13657
Radar rdar://problem/69979005
Original Reporter mark (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, TypeChecker
Assignee None
Priority Medium

md5: 0c2fbedba8b4440f9e12f2e520c1aced

Issue Description:

The following usage of the function `drive` is ambiguous, but only when used within a namespace or a method.

func drive(_ variadics: Int...) -> Int {
  return 42
}

func drive(onNext: (() -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil) -> Int {
  return 42
}

// non-ambiguous
drive()

// OR class Driver
// OR struct Driver
enum Driver {
  static func drive(_ variadics: Int...) -> Int {
    return 42
  }

  static func drive(onNext: (() -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil) -> Int {
    return 42
  }
}

// ambiguous
Driver.drive()
@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 5, 2020

Comment by Shai Mishali (JIRA)

This is effecting RxSwift's code base seemingly

@LucianoPAlmeida
Copy link
Collaborator

Does this is a Tensorflow(TF) specific issue? Seem to me like this is a Swift(SR) issue right?
IMO this should be ambiguous in both cases because there's not an explicit rule on the language(as far as I know) that says a variadic overload is preferable than a function with all the parameters optional in this case. I didn't investigate this, but as far as my understanding, there are some things on name lookup that may be causing this behavior for global functions... cc @xedin

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 6, 2020

Comment by Mark Sands (JIRA)

@LucianoPAlmeida oops—I didn't mean to file this under tensor flow. Is it possible to move tickets? Or should I close this and re-file it under the appropriate project?

Edit: I moved the ticket. I should have checked before I pinged you. But thanks for calling that to my attention!

@LucianoPAlmeida
Copy link
Collaborator

Ah no worries 🙂
But as far as the issue I still think that the expected behavior probably should be ambiguous in both cases(global and member function). I remember we have some discussions about ranking overloads involving variadics in SR-11572...

@typesanitizer
Copy link

@swift-ci create

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 6, 2020

Comment by Shai Mishali (JIRA)

@LucianoPAlmeida I don't entirely understand this -

  1. This is for sure a regression in 5.3, since it didn't happen before
  2. I would expect that a variadic splat would expect at least a single argument of type and that 0 won't be a valid option
  3. If the global func isn't ambiguous, there's no reason a static func scoped to a class would — at the very least, it needs to have a unified behavior

@LucianoPAlmeida
Copy link
Collaborator

Hey freak4pc (JIRA User)
Yeah, this is indeed a change of behavior from one version to another, but my point is that variadic parameter functions do match (0 or more arguments), consider this

class A {
  func f(_ param: Int...) {}
}

A().f() // it's ok because variadic functions accept 0 or more arguments. 

So I agree that the behavior should be unified, but as I mentioned above I think it should be ambiguous in both cases (global and member) because there is no specific rule on the language (as far as I know) that tells a function with all parameters defaulted should be favored over a variadic one and vice-versa. I mean why choose one overload over the other?

One could make a case for the default parameter one because it maintains the same behavior as:

enum Driver {
  static func drive(_ variadics: Int...) -> Int {
    return 42
  }

  static func drive() -> Int {
    return 42
  }
}

Driver.drive() // It's ok as it chooses the empty one 

But in fact, the correct here could be ambiguous too but I think the empty param one chosen because of a rule that favors it based o an equal number of arguments

return nArgs == paramCount.first ||
... and change that would be a source compatibility breaking change.

But those are only my thought on this, @xedin or @DougGregor should know that better 🙂

@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 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

3 participants