Skip to content

Stack overflow in LabelDef phase when pattern matching on many complex cases #2903

Closed
@smarter

Description

@smarter

This code compiles fine with Scala 2.11 and 2.12 but stack overflows in Dotty (both with the old and new patmat, even with -optimise):

case class Foo01(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo02(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo03(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo04(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo05(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo06(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo07(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo08(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo09(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo10(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo11(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo12(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo13(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo14(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo15(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo16(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo17(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo18(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo19(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo20(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo21(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo22(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo23(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo24(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo25(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo26(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo27(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo28(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)
case class Foo29(x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int)

object Test {
  def stuff() = {}

  def test(x: Any): Unit = x match {
    case Foo01(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo02(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo03(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo04(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo05(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo06(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo07(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo08(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo09(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo10(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo11(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo13(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo14(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo15(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo17(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo18(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo19(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo20(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo21(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo22(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo23(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo24(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo25(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo26(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo27(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo28(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
    case Foo29(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => stuff()
  }
}

By commenting out 4 cases you can make it go a bit further and only die with a stack overflow in GenBCode.

The corresponding real world code I'm looking at is https://github.com/epfl-lara/stainless/blob/bf0ef122f4d3b3c9a852425e4db9ca55941398bc/frontends/dotty/src/main/scala/stainless/frontends/dotc/CodeExtraction.scala#L674-L1205

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions