Open scabug opened 10 years ago
Imported From: https://issues.scala-lang.org/browse/SI-8634?orig=1 Reporter: Landon Fuller (landonf) Affected Versions: 2.10.4, 2.11.0
@retronym said: Taking a quick look at this:
A slightly leaner test case:
trait SelfTyped {
type Self
}
sealed trait Container { self =>
type Child = SelfTyped { type Self <: self.ChildSelf }
type ChildSelf
def child: Child
}
sealed trait ExampleChild extends SelfTyped
case class Example (child: Example#Child) extends Container {
type Self = Example
type ChildSelf = ExampleChild
}
sealed trait AbstractNode extends ExampleChild { }
sealed case class ConcreteNode () extends AbstractNode { override type Self = ConcreteNode }
object ProofOfConcept {
def processContainer(container: Container): Unit = {
val c: container.Child = container.child
c match {
case n: ConcreteNode => // java.lang.ClassCastException: ConcreteNode cannot be cast to scala.runtime.Null$
n
}
}
}
object Test extends App {
ProofOfConcept.processContainer(Example(ConcreteNode()))
}
Internally, I think the failure comes from our imprecise LUB/GLB computation:
this = {scala.tools.nsc.transform.patmat.MatchTranslation$MatchTranslator$BoundTree@3642}"x1: <empty>.this.SelfTyped{type Self <: container.ChildSelf} with <empty>.this.ConcreteNode{} (binder: <empty>.this.SelfTyped{type Self <: container.ChildSelf}) @ (_: <empty>.this.ConcreteNode)"
// private def typeTestStep(sub: Symbol, subPt: Type) = step(TypeTestTreeMaker(sub, binder, subPt, glbWith(subPt))(pos))()
glb(
SelfTyped{type Self <: container.ChildSelf} with ConcreteNode{},
container.Child
) = Null
A workaround is to upcast the scrutinee of the pattern match to Any
before the type test on _: ConcreteNode
.
The following code will fail at runtime with a ClassCastException triggered by
identity(<value>)
inprocessContainer()
.