Skip to content

Casting of AnyVal types behaves differently based on compile time type #1448

@scabug

Description

@scabug

Consider the following examples:

scala> 1L.asInstanceOf[Int];
res8: Int = 1

scala> (1L : Any).asInstanceOf[Int];
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
	at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source)
	at .<init>(<console>:5)
	at .<clinit>(<console>)
	at RequestResult$$.<init>(<console>:3)
	at RequestResult$$.<clinit>(<console>)
	at RequestResult$$result(<console>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.Nati...

It seems that when you cast AnyVals of known types between eachother the compiler turns them into numeric conversions as with Java. However if you cast an Any to an AnyVal subtype it does not perform these conversions. This seems like very inconsistent behaviour to me (It's also counter to the specced behaviour).

There are two possible fixes here:

  • Remove the behaviour for performing numeric conversion on casts so that the first example would throw a ClassCastException.
  • Change the methods on BoxesRuntime such as unboxToInt so that they cast to Number instead of the appropriate numeric type. This way the same numeric conversions will be applied when you cast an arbitrary type to a value type.

I strongly prefer the former (in particular it's what the spec says should happen). I suspect the latter is the one that will annoy people the least.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions