diff options
-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) } } } |