Better type inference for Scala: send us your problematic cases!

So I just experienced a type inference issue unique to Scala 3 when dealing with custom function interfaces.

In pekko we had defined our own types of functions, i.e.

/**
 * A Function interface. Used to create first-class-functions is Java.
 * `Serializable` is needed to be able to grab line number for Java 8 lambdas.
 * Supports throwing `Exception` in the apply, which the `java.util.function.Function` counterpart does not.
 */
@nowarn("msg=@SerialVersionUID has no effect")
@SerialVersionUID(1L)
@FunctionalInterface
trait Function[-T, +R] extends java.io.Serializable {
  @throws(classOf[Exception])
  def apply(param: T): R
}

from incubator-pekko/Function.scala at 4ac0f00a477873965ee7d52e16faefb1de91fe3a · apache/incubator-pekko · GitHub

When trying to call the following function

def mapConcat[T](f: function.Function[Out, _ <: java.lang.Iterable[T]]): javadsl.Source[T, Mat] =
  new Source(delegate.mapConcat(elem => Util.immutableSeq(f.apply(elem))))

from incubator-pekko/Source.scala at 07df6071928f6f12dafb01c78d792fa26cd5b077 · apache/incubator-pekko · GitHub

using lambda syntax that returns a java.util.List i.e.

streamingPullResult
  .mapConcat((response: StreamingPullResponse) => response.getReceivedMessagesList)

You get the following error

[error] -- [E007] Type Mismatch Error: /Users/mdedetrich/github/incubator-pekko-connectors/google-cloud-pub-sub-grpc/src/main/scala/org/apache/pekko/stream/connectors/googlecloud/pubsub/grpc/javadsl/GooglePubSub.scala:75:21 
[error] 75 |          .mapConcat((response: StreamingPullResponse) => response.getReceivedMessagesList)
[error]    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error]    |         Found:    com.google.pubsub.v1.StreamingPullResponse =>
[error]    |           java.util.List[com.google.pubsub.v1.ReceivedMessage]
[error]    |         Required: org.apache.pekko.japi.function.Function[
[error]    |           com.google.pubsub.v1.StreamingPullResponse, ? <: Iterable[T]]
[error]    |
[error]    |         where:    T is a type variable with constraint 
[error]    |
[error]    | longer explanation available when compiling with `-explain`

Manually specifying the pekko.japi.function.Function function type, i.e.

streamingPullResult
  .mapConcat(
    ((response: StreamingPullResponse) =>
          response.getReceivedMessagesList): pekko.japi.function.Function[StreamingPullResponse,
      java.util.List[ReceivedMessage]])

Solves the issue

On Scala 2.12/2.13 this workaround is not necessary. Also see enable scala3 build for more google connectors by pjfanning · Pull Request #165 · apache/incubator-pekko-connectors · GitHub