summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/UnCurry.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-07-23 09:56:24 +0200
committerJason Zaugg <jzaugg@gmail.com>2014-07-23 10:07:13 +0200
commit926585a3f36f35c9afc3f9ed9fe0ded72f6b7014 (patch)
tree75bf522accac99be17ac4b1460e0a1e58ddaa86d /src/compiler/scala/tools/nsc/transform/UnCurry.scala
parent73fb460c1cd20ee97556ec0867d17efaa795d129 (diff)
downloadscala-926585a3f36f35c9afc3f9ed9fe0ded72f6b7014.tar.gz
scala-926585a3f36f35c9afc3f9ed9fe0ded72f6b7014.tar.bz2
scala-926585a3f36f35c9afc3f9ed9fe0ded72f6b7014.zip
SI-8743 Fix crasher with poly-methods annotated with @varargs
The code that generated the Java varargs forwarder was basing things on the `ValDef-s` of the parameters of the source method. But, their types refer to a type parameter skolems of the enclosing method, which led to a type mismatch when typechecking the forwarder. Instead, I've reworked the code to simply use the `DefDef`-s symbol's info, which *doesn't* refer to skolems. This actually simplifies the surrounding code somewhat; rather than repeated symbols in a map we can just time travel the pre-uncurry method signatures to figure out which params are releated.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/UnCurry.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala41
1 files changed, 16 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 2209aac00f..9b85f1b36a 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -69,7 +69,6 @@ abstract class UnCurry extends InfoTransform
private val byNameArgs = mutable.HashSet[Tree]()
private val noApply = mutable.HashSet[Tree]()
private val newMembers = mutable.Map[Symbol, mutable.Buffer[Tree]]()
- private val repeatedParams = mutable.Map[Symbol, List[ValDef]]()
/** Add a new synthetic member for `currentOwner` */
private def addNewMember(t: Tree): Unit =
@@ -428,7 +427,7 @@ abstract class UnCurry extends InfoTransform
treeCopy.ValDef(p, p.mods, p.name, p.tpt, EmptyTree)
})
- if (dd.symbol hasAnnotation VarargsClass) saveRepeatedParams(dd)
+ if (dd.symbol hasAnnotation VarargsClass) validateVarargs(dd)
withNeedLift(needLift = false) {
if (dd.symbol.isClassConstructor) {
@@ -699,19 +698,12 @@ abstract class UnCurry extends InfoTransform
}
}
-
- /* Analyzes repeated params if method is annotated as `varargs`.
- * If the repeated params exist, it saves them into the `repeatedParams` map,
- * which is used later.
- */
- private def saveRepeatedParams(dd: DefDef): Unit =
+ private def validateVarargs(dd: DefDef): Unit =
if (dd.symbol.isConstructor)
reporter.error(dd.symbol.pos, "A constructor cannot be annotated with a `varargs` annotation.")
- else treeInfo.repeatedParams(dd) match {
- case Nil =>
- reporter.error(dd.symbol.pos, "A method without repeated parameters cannot be annotated with the `varargs` annotation.")
- case reps =>
- repeatedParams(dd.symbol) = reps
+ else {
+ val hasRepeated = mexists(dd.symbol.paramss)(sym => definitions.isRepeatedParamType(sym.tpe))
+ if (!hasRepeated) reporter.error(dd.symbol.pos, "A method without repeated parameters cannot be annotated with the `varargs` annotation.")
}
/* Called during post transform, after the method argument lists have been flattened.
@@ -719,7 +711,7 @@ abstract class UnCurry extends InfoTransform
* varargs forwarder.
*/
private def addJavaVarargsForwarders(dd: DefDef, flatdd: DefDef): DefDef = {
- if (!dd.symbol.hasAnnotation(VarargsClass) || !repeatedParams.contains(dd.symbol))
+ if (!dd.symbol.hasAnnotation(VarargsClass) || !enteringUncurry(mexists(dd.symbol.paramss)(sym => definitions.isRepeatedParamType(sym.tpe))))
return flatdd
def toArrayType(tp: Type): Type = {
@@ -735,19 +727,18 @@ abstract class UnCurry extends InfoTransform
)
}
- val reps = repeatedParams(dd.symbol)
- val rpsymbols = reps.map(_.symbol).toSet
val theTyper = typer.atOwner(dd, currentClass)
- val flatparams = flatdd.vparamss.head
+ val flatparams = flatdd.symbol.paramss.head
+ val isRepeated = enteringUncurry(dd.symbol.info.paramss.flatten.map(sym => definitions.isRepeatedParamType(sym.tpe)))
// create the type
- val forwformals = flatparams map {
- case p if rpsymbols(p.symbol) => toArrayType(p.symbol.tpe)
- case p => p.symbol.tpe
+ val forwformals = map2(flatparams, isRepeated) {
+ case (p, true) => toArrayType(p.tpe)
+ case (p, false)=> p.tpe
}
val forwresult = dd.symbol.tpe_*.finalResultType
val forwformsyms = map2(forwformals, flatparams)((tp, oldparam) =>
- currentClass.newValueParameter(oldparam.name, oldparam.symbol.pos).setInfo(tp)
+ currentClass.newValueParameter(oldparam.name.toTermName, oldparam.pos).setInfo(tp)
)
def mono = MethodType(forwformsyms, forwresult)
val forwtype = dd.symbol.tpe match {
@@ -761,13 +752,13 @@ abstract class UnCurry extends InfoTransform
// create the tree
val forwtree = theTyper.typedPos(dd.pos) {
- val locals = map2(forwParams, flatparams) {
- case (_, fp) if !rpsymbols(fp.symbol) => null
- case (argsym, fp) =>
+ val locals = map3(forwParams, flatparams, isRepeated) {
+ case (_, fp, false) => null
+ case (argsym, fp, true) =>
Block(Nil,
gen.mkCast(
gen.mkWrapArray(Ident(argsym), elementType(ArrayClass, argsym.tpe)),
- seqType(elementType(SeqClass, fp.symbol.tpe))
+ seqType(elementType(SeqClass, fp.tpe))
)
)
}