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

Instantiating a generic value class results in a class cast exception when given a primitive array #7521

Closed
scabug opened this issue May 27, 2013 · 7 comments
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented May 27, 2013

scala> class Wrapper[Repr](val xs: Repr) extends AnyVal
defined class Wrapper

scala> new Wrapper(new Array[Int](1))
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
	at .<init>(<console>:9)
	at .<clinit>(<console>)
	at .<init>(<console>:7)
	at .<clinit>(<console>)
	at $print(<console>)

Similarly:

scala> class Wrap[Repr](val xs: Repr) extends AnyVal
defined class Wrap

scala> implicit class ops[Repr](val xs: Repr) extends AnyVal { def toWrap = new Wrap(xs) }
defined class ops

scala> (new Array[Int](1)).toWrap
java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Integer;
	at .<init>(<console>:9)
	at .<clinit>(<console>)
	at .<init>(<console>:7)
	at .<clinit>(<console>)
	at $print(<console>)

Note the primitive array being cast in the second example.

@scabug
Copy link
Author

scabug commented May 27, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7521?orig=1
Reporter: @axel22
Affected Versions: 2.10.1
See #5353

@scabug
Copy link
Author

scabug commented May 27, 2013

@retronym said:

scala> class C { new Wrapper(new Array[Int](0)) }
defined class C

scala> :javap -v C
...
{
public C();
  Code:
   Stack=2, Locals=1, Args_size=1
   0:	aload_0
   1:	invokespecial	#9; //Method java/lang/Object."<init>":()V
   4:	getstatic	#15; //Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
   7:	iconst_0
   8:	newarray int
   10:	invokevirtual	#19; //Method scala/runtime/ScalaRunTime$.toObjectArray:(Ljava/lang/Object;)[Ljava/lang/Object;
   13:	checkcast	#21; //class "[Ljava/lang/Integer;"
   16:	pop
   17:	return
  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      18      0    this       LC;

  LineNumberTable:
   line 8: 0


}

@scabug
Copy link
Author

scabug commented May 27, 2013

@retronym said:
Culpable code:

scala/scala@39fc4aa84#L1R740
scala/scala@39fc4aa84#L6R283
scala/scala@39fc4aa84#L6R89

erasedValueClassArg(<<Wrapper[Array[Int]]>>) = Array[Integer]

@scabug
Copy link
Author

scabug commented May 27, 2013

@paulp said:
This is fixed in my patch for #5353.

@scabug
Copy link
Author

scabug commented Aug 5, 2014

@gkossakowski said:
The 2.11.2 is out so I'm rescheduling the issue for 2.11.3.

@scabug
Copy link
Author

scabug commented Nov 4, 2014

@retronym said:
Updating fix-by version to 2.11.5.

@scabug
Copy link
Author

scabug commented Nov 10, 2014

@retronym said:
scala/scala#4124

@scabug scabug closed this as completed Nov 21, 2014
@scabug scabug added this to the 2.12.0-M1 milestone Apr 7, 2017
bsloane1650 pushed a commit to bsloane1650/incubator-daffodil that referenced this issue Dec 17, 2019
Scala 2.11 requires a special implementation of DataValue to work around scala/bug#7521
bsloane1650 pushed a commit to bsloane1650/incubator-daffodil that referenced this issue Dec 17, 2019
Scala 2.11 requires a special implementation of DataValue to work around scala/bug#7521
bsloane1650 pushed a commit to bsloane1650/incubator-daffodil that referenced this issue Dec 17, 2019
Scala 2.11 requires a special implementation of DataValue to work around scala/bug#7521
bsloane1650 added a commit to bsloane1650/incubator-daffodil that referenced this issue Dec 18, 2019
For performance reasons, we have been making extensive use of
AnyRef to store data values in our infoset, and throughout the runtime.
This allows us to avoid boxing, but prevents the type system from validating
that unexepected types to not infect our values.

This commit introduces a value type, DataValue, which provides a 0 overhead (eg. no boxing)
wrapper around AnyRef, while only allowing a limited number of types to populate it.

In doing so, an unrelated bug of mixing Java and Scala BigInts was uncovered and corrected.
Such a bug should be much less likely to occur in the future.

Due to a bug in Scala 2.11 (scala/bug#7521), we have 2 implementations
of DataValue. The 2.11 version automatically boxes/unboxes all instances of Array[Byte]

DAFFODIL-2169
bsloane1650 added a commit to apache/daffodil that referenced this issue Dec 18, 2019
For performance reasons, we have been making extensive use of
AnyRef to store data values in our infoset, and throughout the runtime.
This allows us to avoid boxing, but prevents the type system from validating
that unexepected types to not infect our values.

This commit introduces a value type, DataValue, which provides a 0 overhead (eg. no boxing)
wrapper around AnyRef, while only allowing a limited number of types to populate it.

In doing so, an unrelated bug of mixing Java and Scala BigInts was uncovered and corrected.
Such a bug should be much less likely to occur in the future.

Due to a bug in Scala 2.11 (scala/bug#7521), we have 2 implementations
of DataValue. The 2.11 version automatically boxes/unboxes all instances of Array[Byte]

DAFFODIL-2169
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

2 participants