diff options
author | Paul Phillips <paulp@improving.org> | 2013-08-17 09:18:27 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-08-17 10:58:13 -0700 |
commit | a2189f48084b71a25725fedb7808aba2e71715ad (patch) | |
tree | 125bfedd9bf7ea2eb9cc6079abc22b110fb649be /src/compiler | |
parent | 35775a8fc87e9f3538e13e8d26f9b151138efe8c (diff) | |
download | scala-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.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 25 |
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. |