scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

Impossible for Scala 2.12 to handle overloaded Java method that contains both varargs and parameters of same type #12765

Closed mdedetrich closed 10 months ago

mdedetrich commented 1 year ago

Question for anyone that is still familiar with Scala 2.12 (specifically 2.12.17), I seem to have found a compiler bug that I cannot get around. Assuming that we have 2 java methods (these methods are actually from slf4j)

    /**
     * Log a message at the DEBUG level according to the specified format
     * and arguments.
     * <p/>
     * <p>This form avoids superfluous object creation when the logger
     * is disabled for the DEBUG level. </p>
     *
     * @param format the format string
     * @param arg1   the first argument
     * @param arg2   the second argument
     */
    public void debug(String format, Object arg1, Object arg2);

    /**
     * Log a message at the DEBUG level according to the specified format
     * and arguments.
     * <p/>
     * <p>This form avoids superfluous string concatenation when the logger
     * is disabled for the DEBUG level. However, this variant incurs the hidden
     * (and relatively small) cost of creating an <code>Object[]</code> before invoking the method,
     * even if this logger is disabled for DEBUG. The variants taking
     * {@link #debug(String, Object) one} and {@link #debug(String, Object, Object) two}
     * arguments exist solely in order to avoid this hidden cost.</p>
     *
     * @param format    the format string
     * @param arguments a list of 3 or more arguments
     */
    public void debug(String format, Object... arguments);

It seems to be impossible for Scala 2.12 to call either these methods. In other words no matter what you do you will always get an

[error] /Users/mdedetrich/github/incubator-pekko-persistence-r2dbc/core/src/main/scala/akka/persistence/r2dbc/internal/R2dbcExecutor.scala:306:15: ambiguous reference to overloaded definition,
[error] both method debug in trait Logger of type (x$1: String, x$2: Object*)Unit
[error] and  method debug in trait Logger of type (x$1: String, x$2: Any, x$3: Any)Unit

where as in Java it would pick the public void debug(String format, Object arg1, Object arg2) version over public void debug(String format, Object... arguments); if you only supply arg1 and arg2 (and this is even stated as such in the documentation).

I tried using various ways to force the type (i.e. : Object or .asInstanceOf[Object]) but nothing seems to help. Even

log.debug("test", new Object, new Object)

Will fail to compile.

Pinging @som-snytt because I think you have the most experience here and actually worked on similar bugs

mdedetrich commented 1 year ago

So I managed to find a "solution" to this issue which to me appears more like a workaround then a solution. It turns out if I do

log.debug("test", new Object: Any, new Object: Any)

It manages to compile. The reason why I call this is a workaround is that it only seems to work in the case where you have two such overloads

public void debug(String format, Object arg1, Object arg2);
public void debug(String format, Object... arguments);

And specifically have 3 parameters

som-snytt commented 1 year ago

The PR on Any and Object says backport candidate but the comments are not encouraging on that score. I think ascribing Any is the workaround.

mdedetrich commented 1 year ago

It manages to compile. The reason why I call this is a workaround is that it only seems to work in the case where you have two such overloads

public void debug(String format, Object arg1, Object arg2);
public void debug(String format, Object... arguments);

And specifically have 3 parameters

Incase this is not clear, in other cases I have to methods such as .box (i.e. https://github.com/apache/incubator-pekko-persistence-r2dbc/pull/5/files#diff-7cbfbeca88cff2feb131206c0b3f481f599aa39915c546d60f13cb308c6ff867R289) because Any doesn't work.

The PR on Any and Object says backport candidate but the comments are not encouraging on that score. I think ascribing Any is the workaround.

Are you talking about a scala compiler PR which theoretically solves the issue? If so can you link it, I am curious about what is actually causing the issue

som-snytt commented 1 year ago

https://github.com/scala/scala/pull/7966 but there are several related tickets. It doesn't read like a novel.

som-snytt commented 1 year ago

For boxing, I just closed https://github.com/scala/bug/issues/8661

SethTisue commented 10 months ago

closing since it's 2.12-only and our policy is not to keep such tickets open. (regardless, the ticket has value as documentation and as a place to discuss workarounds; thanks.)

som-snytt commented 10 months ago

I've forgotten if https://github.com/scala/scala/pull/10378 was also this.