bug icon indicating copy to clipboard operation
bug copied to clipboard

bad explicitouter/erasure interaction regarding transform of isInstanceOf[Outer.this.Module.type] to eq(Outer.this.Module)

Open scabug opened this issue 12 years ago • 7 comments

package com.middlewareman

trait Component

case class Event(component: Component)

class Owner {

  object Timestamp extends Component {
    val state = System.currentTimeMillis()
    def unapply(name: Timestamp.type) = Some(name.state)
  }

  val handler: PartialFunction[Event, Unit] = {
    case Event(Timestamp(time)) => println(time)
  }

}

I have not tried compiling outside Eclipse.

scabug avatar Jun 20 '13 15:06 scabug

Imported From: https://issues.scala-lang.org/browse/SI-7598?orig=1 Reporter: Andreas Nyberg (middlewareman) Affected Versions: 2.10.1, 2.10.2 Attachments:

  • SI-7598.log (created on Jun 20, 2013 3:06:59 PM UTC, 28417 bytes)

scabug avatar Jun 20 '13 15:06 scabug

Andreas Nyberg (middlewareman) said: Eclipse event details attached.

scabug avatar Jun 20 '13 15:06 scabug

@retronym said: Minimized:

class Outer {
  object X

  class Inner {
    null.isInstanceOf[X.type]
  }
}

Erasure converts instanceOf tests against singleton types to eq.

              targ.tpe match {
                case SingleType(_, _) | ThisType(_) | SuperType(_, _) =>
                  val cmpOp = if (targ.tpe <:< AnyValTpe) Any_equals else Object_eq
                  atPos(tree.pos) {
                    Apply(Select(qual, cmpOp), List(gen.mkAttributedQualifier(targ.tpe)))
                  }

After erasure:

  class Outer$Inner#8101 extends Object#145 {
    <synthetic> <paramaccessor> <artifact> protected val $outer#15239: Outer#7816 = _;
    <synthetic> <stable> <artifact> def $outer#15238(): Outer#7816 = Outer$Inner#8101.this.$outer#15239;
    def <init>#13449($outer#15240: Outer#7816): Outer$Inner#8101 = {
      if ($outer#15240.eq#5861(null))
        throw null
      else
        Outer$Inner#8101.this.$outer#15239 = $outer#15240;
      Outer$Inner#8101.super.<init>#3011();
      null.eq#5861(Outer#7816.this.X#8099());
      ()
    }

We either need explicit outer to transform TypeTrees to subsitute Outer.this with $outer.type, or change erasure to make the reference to the term Outer.this.xexplicitly pass through$outer`.

scabug avatar Oct 21 '13 09:10 scabug

@retronym said: https://github.com/scala/scala/pull/3066

scabug avatar Oct 21 '13 11:10 scabug

@adriaanm said: Ping – looks like this will go to 2.11.1-RC1?

scabug avatar Feb 09 '14 23:02 scabug

@retronym said: Yep. My principled fix was almost there but had some undiagnosed infinite recursions in the wild. My less principled fix (have erasure selectively call the explicitouter transformer) was a bit too much of a hack.

scabug avatar Feb 10 '14 16:02 scabug

@adriaanm said: This reminds me -- the spec defines isInstanceOf in terms of matching on type patterns, but that would entail y.isInstanceOf[x.type] should compile to y eq x, which actually breaks the compiler ("someone" cast a global to another global...)

scabug avatar Feb 26 '15 01:02 scabug

Somehow, some way, got fixed in 2.13.6 – no compiler crash. Remains fixed in 3.2.2.

SethTisue avatar Apr 07 '23 21:04 SethTisue

https://github.com/scala/scala/pull/9504 perchance

but the retronym minimization waited for https://github.com/scala/scala/pull/9581 fixing https://github.com/scala/bug/issues/12312 which I must have hit while typing idly into REPL during pandemic?

som-snytt avatar Apr 07 '23 22:04 som-snytt