diff options
author | Paul Phillips <paulp@improving.org> | 2012-01-06 15:51:09 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-01-06 19:35:33 -0800 |
commit | d6346f7c567894e635d92fe9408d2b340c93b9b4 (patch) | |
tree | 27639968bcb682eec97df6d7fc2d57cdb65b4c4a /src | |
parent | f39537a369e3b137f5b1bef21cc8f5d86bc9d9d8 (diff) | |
download | scala-d6346f7c567894e635d92fe9408d2b340c93b9b4.tar.gz scala-d6346f7c567894e635d92fe9408d2b340c93b9b4.tar.bz2 scala-d6346f7c567894e635d92fe9408d2b340c93b9b4.zip |
Fix for crasher where Arrays meet abstract types.
This sort of thing was crashing. No longer.
trait Fooz[Q <: Array[_]] { def f0(x: Q) = x.length }
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index b327579c8b..f3b1e77c8d 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -887,8 +887,9 @@ abstract class Erasure extends AddInterfaces fun.symbol != Object_isInstanceOf) => // leave all other type tests/type casts, remove all other type applications preErase(fun) - case Apply(fn @ Select(qual, name), args) if (fn.symbol.owner == ArrayClass) => - if (unboundedGenericArrayLevel(qual.tpe.widen) == 1) + case Apply(fn @ Select(qual, name), args) if fn.symbol.owner == ArrayClass => + // Have to also catch calls to abstract types which are bounded by Array. + if (unboundedGenericArrayLevel(qual.tpe.widen) == 1 || qual.tpe.typeSymbol.isAbstractType) { // convert calls to apply/update/length on generic arrays to // calls of ScalaRunTime.array_xxx method calls global.typer.typedPos(tree.pos)({ @@ -901,14 +902,15 @@ abstract class Erasure extends AddInterfaces } gen.mkRuntimeCall(arrayMethodName, qual :: args) }) - else + } + else { // store exact array erasure in map to be retrieved later when we might // need to do the cast in adaptMember treeCopy.Apply( tree, SelectFromArray(qual, name, erasure(tree.symbol, qual.tpe)).copyAttrs(fn), args) - + } case Apply(fn @ Select(qual, _), Nil) if interceptedMethods(fn.symbol) => if (fn.symbol == Any_## || fn.symbol == Object_##) { // This is unattractive, but without it we crash here on ().## because after |