-
Notifications
You must be signed in to change notification settings - Fork 21
Scalac confused which overload to pick when Java has multiple varargs overloads #8800
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
Comments
Imported From: https://issues.scala-lang.org/browse/SI-8800?orig=1 |
@lrytz said: Now, the Scala compiler does NOT map Object varargs in Java classfiles to Any varargs. public class Test {
public void f(Object o) {
System.out.println("obj");
}
public void g(Object... o) {
System.out.println("obj...");
}
}
scala> val t = new Test
t: Test = Test@1330b682
scala> t.f(1) // works because the Scala compiler thinks f: (Any): Unit
obj
scala> t.g(1) // Scala compiler thinks g: (AnyRef): Unit
<console>:9: error: the result type of an implicit conversion must be more specific than AnyRef
t.g(1)
^ |
Lukas Eder (lukaseder) said: public <T> void h(T... o) {
System.out.println("t...");
} On a bytecode level, T... is really erased again to Object[], but on a language level, there is a lot of (false) type-safety and type-inference that is applied. I'm saying false, because any list of parameters will be viable, in principle. This becomes particularly interesting when the T type has side-effects on the call site, such as: public <T> T h(T... o) {
System.out.println("t...");
return o != null && o.length > 0 ? o[0] : null;
} I wonder if this would produce the same behaviour in Scala as in Java, e.g. (pseudo-repl): scala> 1 == t.h(1)
true |
@som-snytt said: On the linked ticket, I'll contribute the old error message (from 2.9?), which said verbosely that the conversion isn't automatic, but you can "safely use 1.asInstanceOf Integer (jira munches brackets)" or whatever the wording was. There might be better words, too. The current "failed to apply" message is somewhat obscure. scala> foo.f(2, "a", "b") // java methods as in the ticket
res0: String = a&b&
scala> foo.f(2, "a", 1)
<console>:12: error: overloaded method value f with alternatives:
(x$1: Int,x$2: String*)String <and>
(x$1: Int,x$2: Object*)String
cannot be applied to (Int, String, Int)
foo.f(2, "a", 1)
^
scala> foo.f(2, "a", 1: Integer)
res2: String = a/1/ |
Scala is not confused since 2.13. The examples work as... expected. This related ticket also links to dotty discussion.
The Lukas example also compiles and works the way his explanation no longer anticipates. Dotty release will be pushed out to 2025 while the SIP committee figure out how the related example should behave.
|
Given the following Java class:
Scalac gets confused about which overload to pick, as shown below. Casting to
Seq[Object]
resolves the issue.We would expect scala to properly dispatch
fun(1, "a", 12)
to thefun(Int, Seq Object)
overload instead.More info:
The text was updated successfully, but these errors were encountered: