Skip to content

Conversation

@smarter
Copy link
Member

@smarter smarter commented Jul 15, 2015

For a value class V whose underlying type is U, instead of representing
an array of V as V[] on the JVM, we use our own class VCXArray where X
is "U" if U is a primitive type and is "Object" otherwise.

This avoids boxing when creating arrays but we still need to box and
unbox when using such an array in a generic position, this also breaks
reflection and makes it pretty hard to use an array of a value class
from Java or Scala 2.

smarter added 12 commits July 15, 2015 17:33
It will be added by the VCXPrototype parent class
It will be useful to wrap SeqLiterals
This is needed so that Array[T] erases to Object, see the note in the code.
It should be "[Foo" not "[class Foo"
…RefArray

wrapRefArray is defined as:
  def wrapRefArray[T <: AnyRef](xs: Array[T]): WrappedArray[T]
After erasure this becomes:
  def wrapRefArray(xs: Object[]): WrappedArray
This is fine for value classes as long as arrays are boxed, but once we
change the representation this will result in ClassCastException.
Therefore we introduce a wrapper just for value classes:
  def wrapVCArray[T <: AnyVal](xs: Array[T]): WrappedArray[T]
Which is erased to:
  def wrapVCArray(xs: Object): WrappedArray
Which lets us represent arrays of value classes using any reference type.
Note that this mean that the following does not pass Ycheck after VCParents:
  def foo[T <: AnyVal](...)
  foo[Meter](...)
Ycheck will complain that Meter does not conform to the upper bound
AnyVal, which is true. I'm not sure what the best way to deal with this is.
For a value class V whose underlying type is U, instead of representing
an array of V as V[] on the JVM, we use our own class VCXArray where X
is "U" if U is a primitive type and is "Object" otherwise.

This avoids boxing when creating arrays but we still need to box and
unbox when using such an array in a generic position, this also breaks
reflection and makes it pretty hard to use an array of a value class
from Java or Scala 2.

See also the FIXMEs in tests/run/valueclasses-array.scala for the
current implementation restrictions.
Note that this will crash if these methods are present in the source
code, we either needs to disallow them in the source code or find an
alternative design.
This required adding a new magic method Arrays#vcArray to remember the
value class type of a SeqLiteral.
I have no idea why this works better.
@VladUreche
Copy link
Contributor

Cool! Looking forward to this patch making it into dotty! Congrats @smarter and @DarkDimius!

@odersky odersky closed this May 18, 2016
@smarter
Copy link
Member Author

smarter commented May 18, 2016

(Superceded by #1228)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants