Skip to content

Unexpected type widening during inference (behaves differently in Scala 2) #14930

Open
@kitlangton

Description

@kitlangton

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.

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