| [#509] | project: compiler | priority: high | category: bug | |
|---|---|---|---|---|
| submitter | assigned to | status | date submitted | |
| Lex | Martin | fixed | 2005-12-29 17:21:42.0 | |
| subject | growing a ResizableArray causes an array check error | |||
| code |
import scala.collection.mutable._;
object Test extends Application {
val buf = new ArrayBuffer[String];
for(val i <- List.range(0,1000)) {
buf + "hello";
}
Console.println("1000 = " + buf.length);
} |
|||
| what happened | The code crashes when the underlying array is expanded past its initial 16 elements:Exception in thread "main" java.lang.ExceptionInInitializerError at Test.main(arybufgrow.scala) Caused by: java.lang.ArrayStoreException at java.lang.System.arraycopy(Native Method) at scala.runtime.compat.Platform$.arraycopy(Platform.scala:16) at scala.collection.mutable.ResizableArray$class.ensureSize(ResizableArray.scala:34) at scala.collection.mutable.ArrayBuffer.ensureSize(ArrayBuffer.scala:22) at scala.collection.mutable.ArrayBuffer.$plus(ArrayBuffer.scala:37) at Test$$anonfun0.apply(arybufgrow.scala:6) at Test$$anonfun0.apply(arybufgrow.scala:5) at scala.List.foreach(List.scala:690) at Test$. |
|||
| what expected | The code should succeed and print 1000 = 1000 . I found this bug via the XML library, but there is also a compiler crash in the same location when I try to compile sbaz using the new self-bootstrapping compiler. | |||
| [back to overview] | ||||
| Lex edited on 2005-12-29 17:22:18.0 |
| Lex edited on 2005-12-29 17:22:43.0 |
| Martin edited on 2006-01-04 17:25:48.0 |
| This was easy to diagnose but hard to fix. The problem is the call to System.arraycopy which takes to objects and then casts these to arrays. When called with a generic array parameter, arraycopy would instead get the wrapper object, and fail. I added a new Array.copy method which does the correct unwrapping in all cases (of which there are many), and have changed nsc to produce a warning when System.arraycopy is called on generic array arguments. We should take note that this needs to be adapted for .net! |