Pre-SIP: Unboxed wrapper types

If we are working with these types:

class Meter(val toDouble: Double) extends AnyVal

class IntOps(val toInt: Int) extends NewType
class MeterOps(val toMeter: Meter) extends NewType

Then I’d answer your questions as follows:

  • Primitives would have to box in their usual cases. So IntOps boxes to Integer in exactly the cases that Int does (and uses int otherwise).
  • I think that we’d want to erase newtypes before any of the AnyVal rewrites occur. So, we’d potentially have newtype forwarders (essentially static methods taking the underlying type), as well as the whole AnyVal system of forwarders and boxing. So MeterOps would be allowed, and values of that type would be represented identically to Meter at runtime.
  • isInstanceOf[IntOps] could be rewritten to isInstanceOf[Int] or an error. Probably the rewrite makes more sense. Similarly, IntOps could be forbidden in pattern matches, or rewritten to Int.
  • I’m pretty sure we’d want to rewrite classOf[IntOps] and classTag[IntOps] to use Int.
  • Array[IntOps] would be represented as Array[Int].
  • At runtime there are no values of IntOps type, so I don’t think there are special considerations here.

A SIP would require a better formal specification, but I think these are the right properties to want.

1 Like