scala/scala3

Union type inferred unexpectedly

Opened this issue · 0 comments

Compiler version

3.5.0-RC1

Minimized code

import scala.compiletime.ops.int.<

val env: Env[String | Boolean]{
  type Shape = Cons[(1, String), Cons[(2, Boolean), Empty.type]]
} = empty.extended(2, false).extended(1, "string")

trait Env[+V]:
  type Shape <: TList
  def extended[W >: V, U <: W, I <: Int & Singleton]
  (key: I, value: U): Env[W]{ type Shape = Extended[W, Env.this.Shape, I, U] }

val empty: Env[Nothing]{ type Shape = Empty.type } = ???

// Issue goes away when "Unused" is removed (though Scastie Playground crashes).
type Extended[Unused, L <: TList, K <: Int, U] <: Cons[?, ?] = L match
  case Empty.type => Cons[(K, U), Empty.type]
  case Cons[(k, v), tail] => K < k match
    case true => Cons[(K, U), L]

trait TList
case object Empty extends TList
case class Cons[+H, +Tail <: TList](head: H, tail: Tail) extends TList

Compiler Output

Found:    Env[String | Boolean]{
  type Shape = Cons[
    ((1 : Int), String | Boolean), // Unexpected inferred type
    Cons[((2 : Int), Boolean), Empty.type],
  ]
}
Required: Env[String | Boolean]{
  type Shape = Cons[
    ((1 : Int), String),
    Cons[((2 : Int), Boolean), Empty.type],
  ]
}
} = empty.extended(2, false).extended(1, "string")

Expectation

No compile-error