Closed
Description
Minimized code
This code implements type-level addition and multiplication on top of scala.compiletime.S
. The testProd
looks for given evidence that the multiplication commutes for two particular values.
import scala.compiletime.ops.int.S
object InfiniteLoopMatchType {
def main(args: Array[String]): Unit = {
testProd(2, 3) // Infinite loop on Dotty 0.20.0-RC1
}
def testProd(a: Int, b: Int)(using ev: (a.type * b.type) =:= (b.type * a.type)) = true
type *[A <: Int, B <: Int] <: Int = A match {
case 0 => 0
case _ => MultiplyLoop[A, B, 0]
}
type MultiplyLoop[A <: Int, B <: Int, Acc <: Int] <: Int = A match {
case 0 => Acc
case S[aMinusOne] => MultiplyLoop[aMinusOne, B, B + Acc]
}
type +[A <: Int, B <: Int] <: Int = A match {
case 0 => B
case S[aMinusOne] => aMinusOne + S[B]
}
}
Behavior
The compiler loops infinitely (or at least for a very long time, 20+ minutes).
Expectation
The compiler should be able to reduce 2 * 3
and 3 * 2
to 6
, and trivially find an implicit for 6 =:= 6
.
Narrowing down the issue
The following compiles instantly, which leads me to believe that the issue is with dependently typed methods:
val a: 2 = 2
val b: 3 = 3
implicitly[(a.type * b.type) =:= (b.type * a.type)]
Alternatively, the following definition of type addition compiles faster (~10s) but still quite slowly compared to the implicitly
:
type +[A <: Int, B <: Int] <: Int = A match {
case 0 => B
case S[aMinusOne] => S[aMinusOne + B]
}
Related issues
I did not find any related issues.