Skip to content

endless compilation when deferred inline + match type are used (LTS only) #23110

Open
@road21

Description

@road21

Compiler version

3.3.5 LTS (3.6.4 works as expected)

Minimized code

//> using scala 3.3.5

import scala.compiletime.*

trait InlineFoldR[Acc[_ <: Tuple]]:
  inline def apply[Elem, T <: Tuple](acc: Acc[T]): Acc[Elem *: T]

object InlineFoldR:
  inline def fold[Acc[_ <: Tuple], T <: Tuple](
      acc: Acc[EmptyTuple],
      f: InlineFoldR[Acc]
  ): Acc[T] =
    inline erasedValue[T] match
      case _: EmptyTuple => acc.asInstanceOf[Acc[T]]
      case _: (h1 *: h2 *: h3 *: h4 *: ts) =>
        f[h1, h2 *: h3 *: h4 *: ts](
          f[h2, h3 *: h4 *: ts](
            f[h3, h4 *: ts](f[h4, ts](fold[Acc, ts](acc, f)))
          )
        ).asInstanceOf[Acc[T]]
      case _: (h *: ts) =>
        f[h, ts](fold[Acc, ts](acc, f)).asInstanceOf[Acc[T]]

type DropUnits[A <: Tuple] <: Tuple = A match
  case hd *: tl =>
    hd match
      case Unit => DropUnits[tl]
      case Any  => hd *: DropUnits[tl]
  case EmptyTuple => EmptyTuple

object DropUnits:
  object DropInlined extends InlineFoldR[[T <: Tuple] =>> T => DropUnits[T]]:
    inline def apply[Elem, T <: Tuple](
        acc: T => DropUnits[T]
    ): (Elem *: T) => DropUnits[Elem *: T] =
      (elem: Elem *: T) =>
        inline erasedValue[Elem & Matchable] match
          case _: Unit => acc(elem.tail)
          case _       => elem.head *: acc(elem.tail)

  inline def drop[A <: Tuple](a: A): DropUnits[A] =
    InlineFoldR
      .fold[[T <: Tuple] =>> T => DropUnits[T], A](
        (_: EmptyTuple) => EmptyTuple,
        DropInlined
      )(a)

val a: (
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Int,
    Unit,
    Int,
    Unit
) =
  (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, (), 1, ())

println(DropUnits.drop(a))

Output

Endless compilation

Expectation

Compilation succeeded.

Sorry, I don't know how to minimize it. Deferred inline InlineFoldR and match type DropUnits are required to show the bug.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions