Closed
Description
The folowing pattern match produces buggy code when hoistLabels
is applied in PatternMatcher
.
This code can crate bytecode that crashes the JVM.
class TreeAccumulator2 {
def foo(tasty: Tasty2)(tree: Any): Unit = {
import tasty._
tree match {
case A() =>
case B() =>
case C() =>
case D() =>
}
}
}
abstract class Tasty2 {
type X
type Y
implicit def xct: scala.reflect.ClassTag[X]
implicit def yct: scala.reflect.ClassTag[Y]
val A: AExtractor
trait AExtractor {
def unapply(x: X): Boolean
}
val B: BExtractor
trait BExtractor {
def unapply(x: X): Boolean
}
val C: CExtractor
trait CExtractor {
def unapply(x: Y): Boolean // Note the type Y
}
val D: DExtractor
trait DExtractor {
def unapply(x: X): Boolean
}
}
exception while typing package <empty> {
@scala.annotation.internal.SourceFile("tests/pos/tasty-pat-match.scala") class
TreeAccumulator2() extends Object() {
def foo(tasty: Tasty2)(tree: Any): Unit =
{
{
case val x1: Any(tree) = tree
def case1(): Unit = throw new MatchError(x1)
def case2(case x21: Option[tasty.X]): Unit =
if x21.isEmpty.unary_! then
{
case val x3: tasty.X = x21.get
if x3.asInstanceOf[Object].ne(null).&&(tasty.D.unapply(x3)) then
{
()
}
else case1()
}
else case1()
def case3(case x17: Option[tasty.X]): Unit =
{
case val x5: Option[tasty.Y] = tasty.yct.unapply(x1)
if x5.isEmpty.unary_! then
{
case val x6: tasty.Y = x5.get
if x6.asInstanceOf[Object].ne(null).&&(tasty.C.unapply(x6))
then
{
()
}
else case2(x17)
}
else case2(x17)
}
def case4(case x14: Option[tasty.X]): Unit =
{
case val x9: tasty.X = x14.get
if x9.asInstanceOf[Object].ne(null).&&(tasty.B.unapply(x9)) then
{
()
}
else case3(x14)
}
if x1.asInstanceOf[Object].ne(null) then
{
case val x11: Option[tasty.X] = tasty.xct.unapply(x1)
if x11.isEmpty.unary_! then
{
case val x12: tasty.X = x11.get
if x12.asInstanceOf[Object].ne(null).&&(tasty.A.unapply(x12))
then
{
()
}
else case4(x11)
}
else case3(x14)
}
else case1()
}
}
}
@scala.annotation.internal.SourceFile("tests/pos/tasty-pat-match.scala")
abstract
class Tasty2() extends Object() {
type X
type Y
implicit def xct: ClassTag[Tasty2.this.X]
implicit def yct: ClassTag[Tasty2.this.Y]
val A: Tasty2.this.AExtractor
<trait> interface trait AExtractor() extends Object {
def unapply(x: Tasty2.this.X): Boolean
}
val B: Tasty2.this.BExtractor
<trait> interface trait BExtractor() extends Object {
def unapply(x: Tasty2.this.X): Boolean
}
val C: Tasty2.this.CExtractor
<trait> interface trait CExtractor() extends Object {
def unapply(x: Tasty2.this.Y): Boolean
}
val D: Tasty2.this.DExtractor
<trait> interface trait DExtractor() extends Object {
def unapply(x: Tasty2.this.X): Boolean
}
}
}
The error is that the last call to case3
has x14
as parameter but it should have x11
.