You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// PrivateVal.scalacaseclassFoo(privatevalx:Int, y: Option[Int], z: Boolean)
objectPrivateValextendsApp {
deffoo(x: Foo) = x match {
caseFoo(x, Some(y), z) => y
caseFoo(x, y, z) =>0
}
valx=Foo(1, Some(2), false)
println(foo(x))
}
Compiling using 2.10.0-M1 gives us:
PrivateVal.scala:3: error: isInstanceOf cannot test if value types are references.
def foo(x: Foo) = x match {
^
one error found
if we change method foo to
deffoo(x: Foo) = x match {
caseFoo(x, Some(y), z) => y
caseFoo(x, None, z) =>0
}
the code compiles but throws CCE at runtime:
/scala PrivateVal
java.lang.ClassCastException: java.lang.Boolean cannot be cast to scala.Option
at PrivateVal$.foo(PrivateVal.scala:4)
at PrivateVal$delayedInit$body.apply(PrivateVal.scala:9)
Ouch! If you compile it with -Xprint:cleanup you'll notice:
deffoo(x: Foo):Int= {
<synthetic> valtemp2:Foo= x;
if (temp2.ne(null))
{
<synthetic> valtemp4:Boolean= temp2.z();
valy:Option= scala.Boolean.box(temp4).$asInstanceOf[Option]();
if (PrivateVal.this.gd1$1(y))
...
Which means pattern matching is completely confused about the arity (and thus types) of our case class.
Both definitions of foo this worked in 2.9.x so it's a regression. However, the whole idea of having private vals in case classes feels weird. We declare a member to be private but then we can access it through a pattern match (in 2.9.x). I think we should simply disallow private vals in case class's primary constructor. Proposed way to move forward:
bring back questionable semantics of 2.9.x back to master
Deprecate private vals in primary constructor of a case class
Disallow it in the next major release of Scala
PS. -Yvirtpatmat fails to handle private vals properly as well.
PS2. The test-case has been extracted with blood and tears from specs2 by me and Nada Amin.
The text was updated successfully, but these errors were encountered:
Unless you mean "disallow private vals but not private vars", but it seems unlikely you mean that since it would be inexplicable and also wouldn't remove any problem we have.
@hubertp said:
re 2) I remember we had similar discussion with private[this], which we disallowed. I don't remember the ticket but there might be some discussion related to private vals as well.
Compiling using 2.10.0-M1 gives us:
if we change method foo to
the code compiles but throws CCE at runtime:
Ouch! If you compile it with -Xprint:cleanup you'll notice:
Which means pattern matching is completely confused about the arity (and thus types) of our case class.
Both definitions of foo this worked in 2.9.x so it's a regression. However, the whole idea of having private vals in case classes feels weird. We declare a member to be private but then we can access it through a pattern match (in 2.9.x). I think we should simply disallow private vals in case class's primary constructor. Proposed way to move forward:
PS.
-Yvirtpatmat
fails to handle private vals properly as well.PS2. The test-case has been extracted with blood and tears from specs2 by me and Nada Amin.
The text was updated successfully, but these errors were encountered: