summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-08-17 09:18:27 -0700
committerPaul Phillips <paulp@improving.org>2013-08-17 10:58:13 -0700
commita2189f48084b71a25725fedb7808aba2e71715ad (patch)
tree125bfedd9bf7ea2eb9cc6079abc22b110fb649be
parent35775a8fc87e9f3538e13e8d26f9b151138efe8c (diff)
downloadscala-a2189f48084b71a25725fedb7808aba2e71715ad.tar.gz
scala-a2189f48084b71a25725fedb7808aba2e71715ad.tar.bz2
scala-a2189f48084b71a25725fedb7808aba2e71715ad.zip
Expanded logic in formalTypes.
Made the super unusual move (for me) of making a method longer instead of shorter, because I had quite a time modifying the logic as it was. Ideally we wouldn't use this method because it is much less efficient than necessary. If one is typing a call like this: def f(xs: Int*) f(p1, p2, p3, ..., p500) Then it is not necessary to create a list with 500 IntTpes. Once you run out of non-varargs types, every argument which remains can be typed against the vararg type directly.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 2f86e23415..c8377fde95 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -25,18 +25,27 @@ trait Infer extends Checkable {
/** The formal parameter types corresponding to `formals`.
* If `formals` has a repeated last parameter, a list of
- * (nargs - params.length + 1) copies of its type is returned.
- * By-name types are replaced with their underlying type.
+ * (numArgs - numFormals + 1) copies of its type is appended
+ * to the other formals. By-name types are replaced with their
+ * underlying type.
*
* @param removeByName allows keeping ByName parameters. Used in NamesDefaults.
* @param removeRepeated allows keeping repeated parameter (if there's one argument). Used in NamesDefaults.
*/
- def formalTypes(formals: List[Type], nargs: Int, removeByName: Boolean = true, removeRepeated: Boolean = true): List[Type] = {
- val formals1 = if (removeByName) formals mapConserve dropByName else formals
- if (isVarArgTypes(formals1) && (removeRepeated || formals.length != nargs)) {
- val ft = formals1.last.dealiasWiden.typeArgs.head
- formals1.init ::: (for (i <- List.range(formals1.length - 1, nargs)) yield ft)
- } else formals1
+ def formalTypes(formals: List[Type], numArgs: Int, removeByName: Boolean = true, removeRepeated: Boolean = true): List[Type] = {
+ val numFormals = formals.length
+ val formals1 = if (removeByName) formals mapConserve dropByName else formals
+ val expandLast = (
+ (removeRepeated || numFormals != numArgs)
+ && isVarArgTypes(formals1)
+ )
+ def lastType = formals1.last.dealiasWiden.typeArgs.head
+ def expanded(n: Int) = (1 to n).toList map (_ => lastType)
+
+ if (expandLast)
+ formals1.init ::: expanded(numArgs - numFormals + 1)
+ else
+ formals1
}
/** Sorts the alternatives according to the given comparison function.