- Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Description
Compiler version
3.1.1, 3.1.2-RC1
Minimized code
import scala.compiletime.ops.int.* type Fill[N <: Int, A] <: Tuple = N match { case 0 => EmptyTuple case S[n] => A *: Fill[n, A] } sealed trait SeqToTuple[N <: Int] { def apply[A](s: Seq[A]): Fill[N, A] } implicit val emptyToZero: SeqToTuple[0] = new SeqToTuple[0] { override def apply[A](s: Seq[A]): EmptyTuple = EmptyTuple } implicit def successorToSuccessor[N <: Int](implicit pred: SeqToTuple[N]): SeqToTuple[S[N]] = new SeqToTuple[S[N]] { override def apply[A](s: Seq[A]): Fill[S[N], A] = s.head *: pred(s.tail) // Scala doesn't know that `A *: Fill[N, A]` = `Fill[S[N], A]` for some reason }
Output
Found: A *: Fill[N, A] Required: Fill[compiletime.ops.int.S[N], A] where: N is a type in method successorToSuccessor with bounds <: Int
Expectation
Scala recognizes that Fill[S[N], A]
= A *: Fill[N, A]
(as it is a case of the match type) and lets the program compile.