Skip to content

Infinite loop for given ev with match types on dependently typed method args #7512

Closed
@MaximeKjaer

Description

@MaximeKjaer

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.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions