diff options
author | Paul Phillips <paulp@improving.org> | 2010-09-21 07:40:59 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-09-21 07:40:59 +0000 |
commit | 0dacb8195a2aff3dd4b5e1d3aa0ff883e1113744 (patch) | |
tree | aac52950b33aefdac99629cf8bfb049420cd169f /src/compiler | |
parent | e4a596e91d326636fbd68bd9d2b4fc22bae63f76 (diff) | |
download | scala-0dacb8195a2aff3dd4b5e1d3aa0ff883e1113744.tar.gz scala-0dacb8195a2aff3dd4b5e1d3aa0ff883e1113744.tar.bz2 scala-0dacb8195a2aff3dd4b5e1d3aa0ff883e1113744.zip |
Painstaking elimination of redundant array crea...
Painstaking elimination of redundant array creation code, also
eliminating the lingering usage of "wrapArray" which it has long been
noted can go away after next newstarr and now perhaps it really can. A
very careful patch so I'll say no review, but it's a bit of a sensitive
area so feel free to go reviewing anyway.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeGen.scala | 37 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 18 |
2 files changed, 27 insertions, 28 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index f43a1a6ae3..a886e7468f 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -304,13 +304,11 @@ abstract class TreeGen { def mkModuleAccessDcl(accessor: Symbol) = DefDef(accessor setFlag lateDEFERRED, EmptyTree) - def mkRuntimeCall(meth: Name, args: List[Tree]): Tree = { + def mkRuntimeCall(meth: Name, args: List[Tree]): Tree = Apply(Select(mkAttributedRef(ScalaRunTimeModule), meth), args) - } - def mkRuntimeCall(meth: Name, targs: List[Type], args: List[Tree]): Tree = { + def mkRuntimeCall(meth: Name, targs: List[Type], args: List[Tree]): Tree = Apply(TypeApply(Select(mkAttributedRef(ScalaRunTimeModule), meth), targs map TypeTree), args) - } /** Make a synchronized block on 'monitor'. */ def mkSynchronized(monitor: Tree, body: Tree): Tree = @@ -335,19 +333,32 @@ abstract class TreeGen { def mkForwarder(target: Tree, vparamss: List[List[Symbol]]) = (target /: vparamss)((fn, vparams) => Apply(fn, vparams map paramToArg)) - /** Applies a wrapArray call to an array, making it a WrappedArray + /** Applies a wrapArray call to an array, making it a WrappedArray. + * Don't let a reference type parameter be inferred, in case it's a singleton: + * apply the element type directly. */ def mkWrapArray(tree: Tree, elemtp: Type) = { - val predef = mkAttributedRef(PredefModule) - val meth = - if ((elemtp <:< AnyRefClass.tpe) && !isPhantomClass(elemtp.typeSymbol) || - isValueClass(elemtp.typeSymbol)) - Select(predef, "wrapArray") - else - TypeApply(Select(predef, "genericWrapArray"), List(TypeTree(elemtp))) - Apply(meth, List(tree)) + val sym = elemtp.typeSymbol + val meth: Name = + if (isValueClass(sym)) "wrap"+sym.name+"Array" + else if ((elemtp <:< AnyRefClass.tpe) && !isPhantomClass(sym)) "wrapRefArray" + else "genericWrapArray" + + if (isValueClass(sym)) + Apply(Select(mkAttributedRef(PredefModule), meth), List(tree)) + else + Apply(TypeApply(Select(mkAttributedRef(PredefModule), meth), List(TypeTree(elemtp))), List(tree)) } + /** Generate a cast for tree Tree representing Array with + * elem type elemtp to expected type pt. + */ + def mkCastArray(tree: Tree, elemtp: Type, pt: Type) = + if (elemtp.typeSymbol == AnyClass && isValueClass(tree.tpe.typeArgs.head.typeSymbol)) + mkCast(mkRuntimeCall("toObjectArray", List(tree)), pt) + else + mkCast(tree, pt) + /** Try to convert Select(qual, name) to a SelectFromTypeTree. */ def convertToSelectFromType(qual: Tree, name: Name): Tree = { diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 8e3722dd99..f5d6f63b12 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -397,24 +397,12 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { def arrayToSequence(tree: Tree, elemtp: Type) = { atPhase(phase.next) { localTyper.typedPos(pos) { - val predef = gen.mkAttributedRef(PredefModule) - val meth = - if ((elemtp <:< AnyRefClass.tpe) && !isPhantomClass(elemtp.typeSymbol)) - TypeApply(Select(predef, "wrapRefArray"), List(TypeTree(elemtp))) - else if (isValueClass(elemtp.typeSymbol)) - Select(predef, "wrap"+elemtp.typeSymbol.name+"Array") - else - TypeApply(Select(predef, "genericWrapArray"), List(TypeTree(elemtp))) val pt = arrayType(elemtp) val adaptedTree = // might need to cast to Array[elemtp], as arrays are not covariant if (tree.tpe <:< pt) tree - else gen.mkCast( - if (elemtp.typeSymbol == AnyClass && isValueClass(tree.tpe.typeArgs.head.typeSymbol)) - gen.mkRuntimeCall("toObjectArray", List(tree)) - else - tree, - arrayType(elemtp)) - Apply(meth, List(adaptedTree)) + else gen.mkCastArray(tree, elemtp, pt) + + gen.mkWrapArray(adaptedTree, elemtp) } } } |