bad explicitouter/erasure interaction regarding transform of isInstanceOf[Outer.this.Module.type] to eq(Outer.this.Module)
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.
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)
Andreas Nyberg (middlewareman) said: Eclipse event details attached.
@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`.
@retronym said: https://github.com/scala/scala/pull/3066
@adriaanm said: Ping – looks like this will go to 2.11.1-RC1?
@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.
@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...)
Somehow, some way, got fixed in 2.13.6 – no compiler crash. Remains fixed in 3.2.2.
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?