Unexpected case of givens resolution ambiguity on Literal parameter types

Hi,

The following minimalistic code does not compile.

object Operators {

  trait Operator[T <: Singleton & String, IN, OUT]:
    def process(v: IN): OUT

  given Operator["ceil", Float, Int] with {
    override def process(v: Float): Int = math.ceil(v).toInt
  }

  given Operator["floor", Float, Int] with {
    override def process(v: Float): Int = math.floor(v).toInt
  }

  @main
  def testOperators(): Unit = {
    assert(summon[Operator["ceil", Float, Int]].process(1.5f) == 2)
    assert(summon[Operator["floor", Float, Int]].process(1.5f) == 1)
  }
}

Because it considers the two defined givens as equivalent (?), even if they differ on the first literal type parameter value.

From the error, it seems that the literal type is not considered at some stage of compilation:

given_Operator__Float_Int is already defined as object given_Operator__Float_Int
  given Operator["floor", Float, Int] with {

I would have expected to see something like “given_Operator_ceil_Float_Int”.

However, if I keep only one given and remove the other one, the summon actually does check the literal type, and the program does not compile when I specify a string value not corresponding to the one in the given.(eg summon[Operator[“toto”, Float, Int]] does not compile)

Is there a rationale behind this behavior ?
I’m on scala 3.4.

Thank you !

This happens, because the two anonymous givens get the same internal name: given_Operator__Float_Int.

If you uniquely name the givens yourself, it works.

For example:

given op1: Operator["ceil", Float, Int] with {
  override def process(v: Float): Int = math.ceil(v).toInt
}

given op2: Operator["floor", Float, Int] with {
  override def process(v: Float): Int = math.floor(v).toInt
}
1 Like

This doesn’t look like a resolution error since the code defining the givens is not compiling. I am sure that if you give them explicit names it should work.

The problem seems that the autogenerated name does not include singletons for some reason, that feels like a bug.

In any case, unnamed givens are usually a bad idea so yeah, just name them.