From 0dacb8195a2aff3dd4b5e1d3aa0ff883e1113744 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 21 Sep 2010 07:40:59 +0000 Subject: 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. --- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 37 ++++++++++++++-------- .../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) } } } -- cgit v1.2.3