scala / bug

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

2.12 issue: overloaded method value *** with alternatives: #12880

Closed He-Pin closed 1 year ago

He-Pin commented 1 year ago

Reproduction steps

2.12.18

it works in 2.13 & 3

```scala
import java.util.concurrent.Executor
import java.util.function.BiFunction

trait CompletionStage[T] {
  def handleAsync[U](f: BiFunction[_ >: T, Throwable, _ <: U]): CompletionStage[U]

  def handleAsync[U](f: BiFunction[_ >: T, Throwable, _ <: U],
                     executor: Executor): CompletionStage[U]

  def invoke(): Unit = {
    val executor: Executor = null
    handleAsync[T]((t: T, _: Throwable) => t, executor)
  }
}

## Problem

```scala

[error] C:\Users\hepin\IdeaProjects\overrideIssue\src\main\scala\CompletionStage.scala:12:16: overloaded method value handleAsync with alternatives:
[error]   (f: java.util.function.BiFunction[_ >: T, Throwable, _ <: T],executor: java.util.concurrent.Executor)CompletionStage[T] <and>
[error]   (f: java.util.function.BiFunction[_ >: T, Throwable, _ <: T])CompletionStage[T]
[error]  cannot be applied to ((T, Throwable) => T, java.util.concurrent.Executor)
[error]     handleAsync[T]((t: T, u: Throwable) => t, executor)
[error]                ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

Explain how the above behavior isn't what you expected.

It should compile

And it works if I don't use the SAM

lrytz commented 1 year ago

Could you try to minimize the example further?

it works in 2.13 & 2.14

With 2.13 I get

Test.scala:30: error: polymorphic expression cannot be instantiated to expected type;
 found   : [T(in method identity)]java.util.function.Function[T(in method identity),T(in method identity)]
 required: CompletionStage[T(in trait CompletionStage)] => CompletionStage[T(in trait CompletionStage)]
          .thenCompose(java.util.function.Function.identity())
                                                           ^
1 error

With Scala 3.3.1

-- [E007] Type Mismatch Error: Test.scala:30:59 --------------------------------
30 |          .thenCompose(java.util.function.Function.identity())
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |          Found:    java.util.function.Function[T, T]
   |          Required: ? >: CompletionStage[T²] => ? <: CompletionStage[T²]
   |
   |          where:    T  is a type variable with constraint <: Object
   |                    T² is a type in trait CompletionStage
   |
   | longer explanation available when compiling with `-explain`
-- [E007] Type Mismatch Error: Test.scala:32:54 --------------------------------
32 |    ).thenCompose(java.util.function.Function.identity())
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |          Found:    java.util.function.Function[T, T]
   |          Required: ? >: CompletionStage[T²] => ? <: CompletionStage[T²]
   |
   |          where:    T  is a type variable with constraint <: Object
   |                    T² is a type in trait CompletionStage
   |
   | longer explanation available when compiling with `-explain`
2 errors found
He-Pin commented 1 year ago

@lrytz I have updated the minimlized version.

import java.util.concurrent.Executor
import java.util.function.BiFunction

trait CompletionStage[T] {
  def handleAsync[U](f: BiFunction[_ >: T, Throwable, _ <: U]): CompletionStage[U]

  def handleAsync[U](f: BiFunction[_ >: T, Throwable, _ <: U],
                     executor: Executor): CompletionStage[U]

  def invoke(): Unit = {
    val executor: Executor = null
    handleAsync[T](new BiFunction[T, Throwable, T] {
      override def apply(t: T, u: Throwable): T = ???
    }, executor)
  }
}

and

import java.util.concurrent.Executor
import java.util.function.BiFunction

trait CompletionStage[T] {
  def handleAsync[U](f: BiFunction[_ >: T, Throwable, _ <: U]): CompletionStage[U]

  def handleAsync[U](f: BiFunction[_ >: T, Throwable, _ <: U],
                     executor: Executor): CompletionStage[U]

  def invoke(): Unit = {
    val executor: Executor = null
    handleAsync((t: T, u: Throwable) => t, executor)
  }
}

Can compiles

lrytz commented 1 year ago

Thank you @He-Pin. Since this is a 2.12-only issue I will close it as "fixed in 2.13". There were improvements in overloading resolution in 2.13 that were implemented for supporting the wider use of overloading in the standard library.

He-Pin commented 1 year ago

@lrytz I encounter this when do https://github.com/scala-native/scala-native/pull/3500 ; which I found very annoying..

If this will not be fixed, does that means the community should soon move to 2.13.x? I just saw Akka remove 2.12.x and JDK 8 support.

lrytz commented 1 year ago

When to drop Scala 2.12 support is ultimately up to library maintainers and the community - check with the scala-native maintainers what their plans are. Scala 2.12 itself is still supported and maintained for now.

He-Pin commented 1 year ago

Ok, so this fix is not planned for Scala 2.12 right?

lrytz commented 1 year ago

That's right, we're not planning to backport the overloading resolution improvements from 2.13 to 2.12.