Skip to content

Behavior of overloaded varargs and default parameter value differs from Scala 2 #14765

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

Closed
FlorianCassayre opened this issue Mar 24, 2022 · 4 comments · Fixed by #14775
Closed

Comments

@FlorianCassayre
Copy link
Contributor

Compiler version

3.1.2-RC1 down to 3.0.0

Minimized code

def f(x: Int = 0): Int = 1
def f(x: Int*): Int = 2

println(f())

Output

Prints:

  • 1 in Scala 3
  • 2 in Scala 2

Expectation

Expected the behavior to remain the same as in Scala 2.

This may be intended, but it looks like a regression to me (that could potentially break things silently).

@FlorianCassayre FlorianCassayre added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Mar 24, 2022
@som-snytt
Copy link
Contributor

My vote or guess is that it should drop the application requiring default args before considering specificity. I think Scala 2 is doing that correctly?

@odersky odersky added itype:invalid and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Mar 24, 2022
@odersky
Copy link
Contributor

odersky commented Mar 24, 2022

That looks like a Scala 2 bug to me. The spec in https://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#overloading-resolution says:

A parameterized method 𝑚 of type (𝑝1:𝑇1,…,𝑝𝑛:𝑇𝑛)𝑈 is as specific as some other member 𝑚′ of type 𝑆 if 𝑚′ is applicable to arguments (𝑝1,…,𝑝𝑛) of types 𝑇1,…,𝑇𝑛.

(and the most specific one is chosen). In this case the second vararg method can be applied to a single argument, but the first method with the default argument cannot be applied to a variable number of Ints. So the first method is strictly more specific and should be chosen.

@odersky odersky closed this as completed Mar 24, 2022
@som-snytt
Copy link
Contributor

Before that, it says,

It is an error if none of the members in B\mathscr{B}B is applicable. If there is one single applicable alternative, that alternative is chosen. Otherwise, let CC\mathscr{CC}CC be the set of applicable alternatives which don't employ any default argument in the application to e1,…,eme_1 , \ldots , e_me1​,…,em​.

Both are applicable, so take the set of alternatives which don't employ any default argument in the application.

That will exclude the alternative selected in Scala 3.

@odersky
Copy link
Contributor

odersky commented Mar 24, 2022

Ah, yes, that explains it. We don't implement that step in Scala 3 anymore. I am not sure we should. It seems to be a needless complication of the rules. But we should at least document the difference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants