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

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

Closed
mdedetrich opened this issue Apr 4, 2023 · 7 comments

Comments

@mdedetrich
Copy link

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
Copy link
Author

mdedetrich commented Apr 5, 2023

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
Copy link

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
Copy link
Author

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
Copy link

scala/scala#7966 but there are several related tickets. It doesn't read like a novel.

@som-snytt
Copy link

For boxing, I just closed #8661

@SethTisue
Copy link
Member

SethTisue commented Aug 8, 2023

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.)

@SethTisue SethTisue closed this as not planned Won't fix, can't repro, duplicate, stale Aug 8, 2023
@som-snytt
Copy link

I've forgotten if scala/scala#10378 was also this.

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

No branches or pull requests

3 participants