-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Ambiguous overload between varargs and non-varargs #9688
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
@smarter |
- The biggest change in 0.27.0-RC1 is the change in the extension methods syntax - Because of [#9688](scala/scala3#9688) a temporary fix was applied in calls to `log.xxx` that pass in a single object to log
Turns out this isn't even specific to Java varargs: object Test {
def foo(x: Any*): Unit = {}
def foo(x: Any): Unit = {}
foo("") // error: ambiguous overloads
} |
@odersky Any idea what difference there might be between Scala 2 and Dotty's overloading resolution that leads to the previous example being ambiguous? |
It's also worth noting that the following is not ambiguous in Scala 2 nor Dotty: object Test {
def foo(x: String*): Unit = {}
def foo(x: String): Unit = {}
foo("")
} I don't know why using String instead of Any makes a difference. |
Is it because |
That should be fine, but maybe what's going on is that |
A couple of links via gitter: #6230 still open from a pre-pandemic year, with a long conversation that ends with Martin: "The rabbit hole just got deeper." The canonical scala 2 ticket scala/bug#8342 doesn't actually link to all the issues, we need paulp-level linking. Sample subtlety scala/bug#4728. I think scala/bug#8344 was resolved incorrectly [but what do I know]. Gitter converts links to text so they are no longer cut/pasteable. [Edit: github converts them back. Synergy!] |
We recently merged scala#9601 which unified our handling of `Object` coming from Java methods, an unintended consequence of that change is that some existing Java APIs can no longer be called without running into ambiguity errors, for example log4j defines two overloads for `Logger.error`: (x: String, y: Object): Unit (x: String, y: Object*): Unit previously we translated `Object` to `Any` but left `Object*` alone, now they're both treated the same way (translated to a special alias of `Object`) and so neither method ends up being more specific than the other, so `error("foo: {}, 1)` is now ambiguous. Clearly the problem lies with how we handle varargs in overloading resolution, but this has been a source of issues for years with no clear resolution: - scala/bug#8342 - scala/bug#4728 - scala/bug#8344 - scala#6230 This PR cuts the Gordian knot by simply declaring that non-varargs methods are always more specific than varargs. This has several advantages: - It's an easy rule to remember - It matches what Java does (see https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2) - It avoids unnecessary wrapping of arguments The downside is that it doesn't match what Scala 2 does, but our current behavior isn't a perfect match either (also it seems that Scala 2 handles Java varargs and Scala varargs differently in overloading resolution which is another source of complexity best avoided, see `tests/run/overload_repeated`). Fixes scala#9688, supercedes scala#6230.
It's anoying in Java too foo(Object ... values) //1
foo(List<Object> values) //2
List<String> values = ...
foo(values) //link to 1
List values2 = values;
foo(values2) //link to 2 |
Fixed in #9732 |
* Bump Dotty version * Bump Dotty version to 0.27.0-RC1 - The biggest change in 0.27.0-RC1 is the change in the extension methods syntax - Because of [#9688](scala/scala3#9688) a temporary fix was applied in calls to `log.xxx` that pass in a single object to log * Organise code snippets * Fix extension method syntax/Fix indentation * Switch to Significant Indentation Based Syntax - Switch to SIB syntax for exercise 3 and later * Remove option for .sbtopts that will be deprecated in the future
…ions syntax - Dotty 0.27.0-RC1 broke logging calls due to [Ambiguous overload between varargs and non-varargs #9688](scala/scala3#9688) which was fixed in [Fix vararg overloading #9732](scala/scala3#9732) - Remove a few remaining extension methods that still used an 'older' extension mothod syntax
…ions syntax - Dotty 0.27.0-RC1 broke logging calls due to [Ambiguous overload between varargs and non-varargs #9688](scala/scala3#9688) which was fixed in [Fix vararg overloading #9732](scala/scala3#9732) - Remove a few remaining extension methods that still used an 'older' extension mothod syntax
* Bump Dotty version to Scala 3.0.0-M1/Remove workaround/Correct extensions syntax - Dotty 0.27.0-RC1 broke logging calls due to [Ambiguous overload between varargs and non-varargs #9688](scala/scala3#9688) which was fixed in [Fix vararg overloading #9732](scala/scala3#9732) - Remove a few remaining extension methods that still used an 'older' extension mothod syntax * Update exercise instructions - Exercise on extentions still used a syntax that has since then been changed - Use indentation based syntax in instructions
Minimized code
Calling a method on the Java Log4J library with 2 arguments (the last one in a position where a varargs polymorphic version exists) results in the compiler reporting an error.
context.log.error("Received unexpected message in state 'trackProgress': {}", msg)
Compiling the above line results in the following error message:
Output
Expectation
The sample line of code given above should compile (as it does in pre-0.27.0 and of course Scala 2.x)
The text was updated successfully, but these errors were encountered: