Skip to content

Type inference issue #22781

Open
Open
@gaeljw

Description

@gaeljw

Apologies for the title that is quite vague; I don't know how to better qualify it.

Compiler version

3.6.4

Minimized code

import scala.annotation.nowarn
import scala.concurrent.Future

class InferenceTest {

  trait Endpoint[INPUT] {
    def serverSecurityLogic[F[_]](f: Any => F[Any]): PartialServerEndpoint[INPUT, F] = ???
  }

  class ServerEndpoint[F[_]] {
    type INPUT
  }

  object ServerEndpoint {

    type Full[_INPUT, F[_]] = ServerEndpoint[F] {
      type INPUT = _INPUT
    }
  }

  trait PartialServerEndpoint[INPUT, F[_]] {

    def serverLogicSuccess(f: Any => INPUT => F[Any]): ServerEndpoint.Full[INPUT, F] = ???

    def serverLogic(f: Any => INPUT => F[Any]): ServerEndpoint.Full[INPUT, F] = ???

  }

  private val getEndpoint: Endpoint[Unit] = ???
  private val createEndpoint: Endpoint[Any] = ???

  private def authenticate(jwt: Any): Future[Any] = ???

  private def get(authenticatedUser: Any): Future[Any] = ???
  private def create(authenticatedUser: Any)(createData: Any): Future[Any] = ???

  @nowarn
  private def toRoutes(e: ServerEndpoint[Future]): Unit = toRoutes(List(e))

  private def toRoutes(serverEndpoints: List[ServerEndpoint[Future]]): Unit = ???

  toRoutes(
    List(
      getEndpoint
        .serverSecurityLogic(authenticate).serverLogicSuccess(user => _ => get(user)),
      createEndpoint
        .serverSecurityLogic(authenticate).serverLogic(create)
    )
  )

}

Output

[error] -- [E134] Type Error: .../InferenceTest.scala:44:2 
[error] 44 |  toRoutes(
[error]    |  ^^^^^^^^
[error]    |None of the overloaded alternatives of method toRoutes in class InferenceTest with types
[error]    | (serverEndpoints:
[error]    |  List[InferenceTest.this.ServerEndpoint[scala.concurrent.Future]]): Unit
[error]    | (e: InferenceTest.this.ServerEndpoint[scala.concurrent.Future]): Unit
[error]    |match arguments (List[InferenceTest.this.ServerEndpoint[? >: F[X0] <: F]])
[error]    |
[error]    |where:    F is a type variable with constraint >: scala.concurrent.Future and <: [_] =>> Any
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

Expectation

The strictly identical same code works in Scala 2.13.16 (just changing using to implicit vals in the class declaration).

Hence I would expect it to compile without error in Scala 3 as well.

Workaround

Explicitly typing the list does work but I'm unclear as why it would be required now.

- toRoutes(List(
+ toRoutes(List[ServerEndpoint[Future]](

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions