We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
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
The following code will fail at runtime with a ClassCastException triggered by identity(<value>) in processContainer().
identity(<value>)
processContainer()
trait SelfTyped { type Self } sealed trait Container { self => type Child = SelfTyped { type Self <: self.ChildSelf } type ChildSelf def children: List[Child] } sealed trait ExampleChild extends SelfTyped case class Example (children: List[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 [C <: Container] (container: C): Unit = { container.children.foreach { case n: ConcreteNode => identity(n) // java.lang.ClassCastException: ConcreteNode cannot be cast to scala.runtime.Null$ case _ => } } } ProofOfConcept.processContainer(Example(List(ConcreteNode())))
The text was updated successfully, but these errors were encountered:
Imported From: https://issues.scala-lang.org/browse/SI-8634?orig=1 Reporter: Landon Fuller (landonf) Affected Versions: 2.10.4, 2.11.0
Sorry, something went wrong.
@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.
Any
_: ConcreteNode
No branches or pull requests
The following code will fail at runtime with a ClassCastException triggered by
identity(<value>)
inprocessContainer()
.The text was updated successfully, but these errors were encountered: