diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2015-04-26 00:08:32 +0200 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2015-04-27 17:05:04 +0200 |
commit | 96d75318959156c71628d8878fc5bcf0185821b4 (patch) | |
tree | 74bd40ecfa77d16aecfbb7ff29b2747585924b46 /src/dotty/tools/dotc/typer/TypeAssigner.scala | |
parent | 1e9c012a0c61b2031ecaf11de3f2e99a5fdff7af (diff) | |
download | dotty-96d75318959156c71628d8878fc5bcf0185821b4.tar.gz dotty-96d75318959156c71628d8878fc5bcf0185821b4.tar.bz2 dotty-96d75318959156c71628d8878fc5bcf0185821b4.zip |
TypeAssigner: fix return type of clone() for arrays
Given the following code:
val x: Array[String] = new Array[String](1)
x(0) = "foo"
println(x.clone().apply(0))
Before this commit, the last line was rewritten in Erasure to:
println(x.clone().[]apply(0))
This is incorrect: clone() returns an Object, so a cast is necessary,
this resulted in the following failure at runtime:
java.lang.VerifyError: Bad type on operand stack in aaload
After this commit, the last line is rewritten in Erasure to:
println(x.clone().asInstanceOf[String[]].[]apply(0))
This corresponds to adding a "checkcast" instruction in the generated
bytecode, and is enough to fix the runtime error.
Diffstat (limited to 'src/dotty/tools/dotc/typer/TypeAssigner.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/TypeAssigner.scala | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index 2ec510a3d..d3baad848 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -210,7 +210,13 @@ trait TypeAssigner { case p.arrayApply => MethodType(defn.IntType :: Nil, arrayElemType) case p.arrayUpdate => MethodType(defn.IntType :: arrayElemType :: Nil, defn.UnitType) case p.arrayLength => MethodType(Nil, defn.IntType) - case nme.clone_ if qualType.isInstanceOf[JavaArrayType] => MethodType(Nil, qualType) + + // Note that we do not need to handle calls to Array[T]#clone() specially: + // The JLS section 10.7 says "The return type of the clone method of an array type + // T[] is T[]", but the actual return type at the bytecode level is Object which + // is casted to T[] by javac. Since the return type of Array[T]#clone() is Array[T], + // this is exactly what Erasure will do. + case _ => accessibleSelectionType(tree, qual) } tree.withType(tp) |