Skip to content
New issue

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

Simplify WrappedArray for boxed primitives #10851

Closed
lrytz opened this issue Apr 26, 2018 · 3 comments
Closed

Simplify WrappedArray for boxed primitives #10851

lrytz opened this issue Apr 26, 2018 · 3 comments
Assignees
Milestone

Comments

@lrytz
Copy link
Member

lrytz commented Apr 26, 2018

In 2.12, a mutable.ArraySeq wraps an Array[AnyRef], which means primitives are boxed in the underlying array.

WrappedArray by default uses unboxed arrays for primitives, but it can also wrap an array of boxed primitives.

scala> import scala.collection.mutable.WrappedArray
import scala.collection.mutable.WrappedArray

scala> val a = WrappedArray.make(Array(1))
a: scala.collection.mutable.WrappedArray[Int] = WrappedArray(1)

scala> a.array.getClass
res0: Class[_ <: Array[Int]] = class [I

scala> val a = WrappedArray.make(Array(1): Array[Any]).asInstanceOf[WrappedArray[Int]]
a: scala.collection.mutable.WrappedArray[Int] = WrappedArray(1)

scala> a.array.getClass
res1: Class[_ <: Array[Int]] = class [Ljava.lang.Object;

Can / should we make this easier to do?

Also, can we avoid this problem here:

scala> a.array
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [I

Once things are settled, update the docs at https://github.com/scala/collection-strawman/wiki/FAQ#new-deprecations

@lrytz lrytz added this to the 2.13.0-M4 milestone Apr 26, 2018
@lrytz
Copy link
Member Author

lrytz commented Apr 26, 2018

For creating a WrappedArray[Int] with an underlying array of boxed primitives, there is also

scala> WrappedArray.untagged(1,2,3)
res5: scala.collection.mutable.WrappedArray[Int] = WrappedArray(1, 2, 3)

scala> WrappedArray.untagged(1,2,3).array.getClass
res7: Class[_ <: Array[Int]] = class [Ljava.lang.Object;

@lrytz
Copy link
Member Author

lrytz commented Apr 26, 2018

A related issue:

scala> WrappedArray.untagged(1).elemTag.newArray(1)
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [I

@szeiger
Copy link
Member

szeiger commented May 9, 2018

If we want WrappedArray to allow boxed and unboxed representations we need to drop the element types in elemTag and array, at least in WrappedArray. They are probably safe to keep in the specialized subclasses.

This one per se is more of a puzzler than a bug:

scala> val a = WrappedArray.make(Array(1): Array[Any]).asInstanceOf[WrappedArray[Int]]
a: scala.collection.mutable.WrappedArray[Int] = WrappedArray(1)

Array(1): Array[Any] creates an Array[Object] (not an Array[Int] cast to Array[Any]). If you cast the WrappedArray to WrappedArray[Int] you end up with an Array[Object] pretending to be an Array[Int]. But there are legitimate ways (without a cast) to end up with the same boxed representation (as in your later comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants