Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extraction spoils generic type erasure #12182

Closed
haitaka opened this issue Oct 6, 2020 · 2 comments · Fixed by scala/scala#9254
Closed

Extraction spoils generic type erasure #12182

haitaka opened this issue Oct 6, 2020 · 2 comments · Fixed by scala/scala#9254
Assignees
Labels
erasure fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)
Milestone

Comments

@haitaka
Copy link

haitaka commented Oct 6, 2020

The following code produces a ClassCastException at runtime:

object Test {
  abstract class Base[T] {
    def v: T
  }
  class ImplI extends Base[Int] {
    def v = 42
  }
  object ImplI {
    def unapply(x: ImplI) = Some(x.v)
  }
  class ImplD extends Base[Double] {
    def v = 42.0
  }
  object ImplD {
    def unapply(x: ImplD) = Some(x.v)
  }
  def foo[T](x: Base[T], labels: Seq[T]): Unit = {
    val last: T = labels.last // ClassCastException

    x match {
      // uncomment to fix
      // case ImplI(v) => println(v)
      case ImplD(v) => println(v)
      case ImplI(v) => println(v)
    }
  }
  def main(args: Array[String]): Unit = {
    foo(new ImplI(), Seq(1, 2, 3))
  }
}

Mathing ImplI(_) before ImplD(_) as well as not matching ImplD(_) at all fixes the failure.

Probably related to #8563.

@martijnhoekstra martijnhoekstra added the fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) label Oct 6, 2020
@SethTisue SethTisue changed the title Extraction spolis generic type erasure Extraction spoils generic type erasure Oct 6, 2020
@dwijnand
Copy link
Member

dwijnand commented Oct 7, 2020

Bug in erasure?

The tree goes from this after uncurry:

    def foo[T](x: Main.Base[T], labels: Seq[T]): Unit = {
      val last: T = labels.last();
      {
        case <synthetic> val x1: Main.Base[T] = x;
        case8(){
          if (x1.isInstanceOf[Main.ImplD]())
            {
              <synthetic> val x2: Main.ImplD = (x1.asInstanceOf[Main.ImplD](): Main.ImplD);
              {
                <synthetic> val o10: Some[Double] = Main.this.ImplD.unapply(x2);
                if (o10.isEmpty().unary_!())
                  {
                    val v: Double = o10.get();

to this (after erasure):

    def foo(x: Main.Base, labels: Seq): Unit = {
      val last: Double = unbox(labels.last());
      {
        case <synthetic> val x1: Main.Base = x;
        case8(){
          if (x1.$isInstanceOf[Main.ImplD]())
            {
              <synthetic> val x2: Main.ImplD = (x1.$asInstanceOf[Main.ImplD](): Main.ImplD);
              {
                <synthetic> val o10: Some = Main.this.ImplD.unapply(x2);
                if (o10.isEmpty().unary_!())
                  {
                    val v: Double = unbox(o10.get());

@joroKr21
Copy link
Member

Related: #12194

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
erasure fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants