summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-09-21 07:40:59 +0000
committerPaul Phillips <paulp@improving.org>2010-09-21 07:40:59 +0000
commit0dacb8195a2aff3dd4b5e1d3aa0ff883e1113744 (patch)
treeaac52950b33aefdac99629cf8bfb049420cd169f
parente4a596e91d326636fbd68bd9d2b4fc22bae63f76 (diff)
downloadscala-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.
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala37
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala18
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)
}
}
}