Skip to content

Compiler cannot choose correct overloaded method with default argument #16004

Open
@kpodsiad

Description

@kpodsiad

Compiler version

3.2.0, 3.2.1-RC1, haven't checked earlier versions

Minimized code

Original code
//> using scala "3.2.1-RC1"

//> using lib "org.typelevel::cats-core:2.8.0"
//> using lib "org.typelevel::cats-effect:3.3.11"

import cats.Functor
import cats.Monad
import cats.Parallel
import cats.effect.Concurrent
import cats.effect.IO
import cats.effect.Resource
import cats.effect.Temporal
import cats.syntax.all._

import scala.concurrent.duration.FiniteDuration
import scala.concurrent.duration._

trait Cache[F[_], K, V]

object Cache {

  final case class Refresh[-K, +V](interval: FiniteDuration, value: K => V)

  final case class Config[F[_], -K, V](
      expireAfterRead: FiniteDuration,
      expireAfterWrite: Option[FiniteDuration] = None,
      maxSize: Option[Int] = None,
      refresh: Option[Refresh[K, F[Option[V]]]] = None
  )

  def expiring[F[_]: Concurrent: Temporal: Parallel, K, V](
      expireAfter: FiniteDuration
  ): Resource[F, Cache[F, K, V]] = ???

  def expiring[F[_]: Temporal: Parallel, K, V](
      config: Config[F, K, V],
      partitions: Option[Int] = None
  ): Resource[F, Cache[F, K, V]] = ???

  /* Without partitions being specified, error is yielded */

  val notCompiling = expiring[IO, Int, Int](
    config = Config[IO, Int, Int](expireAfterRead = 1.minute),
  )

  val compiling = expiring[IO, Int, Int](
    config = Config[IO, Int, Int](expireAfterRead = 1.minute),
    partitions = None
  )
}

Minimized reproduction

//> using scala "3.2.1-RC1"

//> using lib "org.typelevel::cats-effect:3.3.11"

import scala.concurrent.duration.FiniteDuration
import scala.concurrent.duration._
import cats.effect.kernel.Resource
import cats.effect.IO

trait Cache[F[_], K, V]

object Cache {

  final case class Config(expireAfterRead: FiniteDuration)

  def expiring[F[_], K, V](
      expireAfter: FiniteDuration
  ): Resource[F, Cache[F, K, V]] = ???

  def expiring[F[_], K, V](
      config: Config,
      partitions: Option[Int] = None
  ): Resource[F, Cache[F, K, V]] = ???

  /* Without partitions being specified, error is yielded */

  val notCompiling = expiring[IO, Int, Int](
    config = Config(expireAfterRead = 1.minute)
  )

  val compiling = expiring[IO, Int, Int](
    config = Config(expireAfterRead = 1.minute),
    partitions = None
  )
}

Output

None of the overloaded alternatives of method expiring in object Cache with types
 [F[_$3], K, V]
  (config: Cache.Config, partitions: Option[Int]): 
    cats.effect.kernel.Resource[F, Cache[F, K, V]]
 [F[_$2], K, V]
  (expireAfter: concurrent.duration.FiniteDuration): 
    cats.effect.kernel.Resource[F, Cache[F, K, V]]
match type arguments [cats.effect.IO, Int, Int] and arguments (Cache.Config)

Expectation

Compiler is able to pick correct overloaded method even without partitions specified explicitly.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions