Force single argument in scala varargs

Spread the love

Question Description

Given a java class with two methods (taken from mockito):

OngoingStubbing thenReturn(T value);

OngoingStubbing thenReturn(T value, T... values);

If I invoke from scala with

....thenReturn("something")

I get an error:

Description Resource    Path    Location    Type
ambiguous reference to overloaded definition, both method thenReturn in trait OngoingStubbing of type (x$1: java.lang.Object, x$2: [java.lang.Object])org.mockito.stubbing.OngoingStubbing[java.lang.Object] and  method thenReturn in trait OngoingStubbing of type (x$1: java.lang.Object)org.mockito.stubbing.OngoingStubbing[java.lang.Object] match argument types (java.lang.String)

And I cannot figure out how to fix this.

Practice As Follows

These answers are all to the wrong question. The difference is subtle, but this is not the same issue as the one in the linked ticket. That one does require unreasonable gymnastics to call the non-varargs method. For this one, the following is enough.

thenReturn[String]("something")

Or, if you didn’t want to do that for some reason, you don’t need the type alias and the cast. You can use a structural type ascription directly.

(this: { def thenReturn[T](s: T): OngoingStubbing[T] }).thenReturn("something")

The issue here is type inference at the intersection of overloading and polymorphism – one method is more specific, but scalac doesn’t figure out which. The issue in SI-2991 is genuine ambiguity due to an interaction between overloading and tuple conversion – neither is more specific.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.