Open
Description
Compiler version
3.1.1
Minimized code
Here's a Scastie with the unexpected behavior in Scala 3. And here's a Scastie with the expected behavior in Scala 2.
Here's the gist:
// Given a constructor that infers types from given a function
def fromFunction[A, B, C](f: (A, B) => C)(implicit tagA: Tag[A], tagB: Tag[B]): Box[A with B] =
Box(Map("a" -> tagA, "b" -> tagB))
// It behaves differently depending on whether or not the call site is ascribed a type
// No type ascription
val box1 = fromFunction((int: Int, string: String) => true)
println(box2) // Infers A and B correctly
// With a type ascription
val box2: Box[Int with String] = fromFunction((int: Int, string: String) => true)
println(box3) // Infers A and B to both be (A & B)
Output
// In the case without the type ascription
Box(Map(a -> Tag[Int], b -> Tag[String]))
// In the case with the type ascription
Box(Map(a -> Tag[{String & Int}], b -> Tag[{String & Int}]))
Expectation
I would expect both cases to infer with a bias toward the input type, which is function of type (Int, String) => Boolean
. So I would expect both cases to print Box(Map(a -> Tag[Int], b -> Tag[String]))
, as it does in the linked Scala 2 version.
Concretely, this is used in ZIO
to generate "Layers" from functions. For now, in Scala 3, it is necessary to either remove the type ascription or create an intermediate val without an ascription.