diff options
author | Som Snytt <som.snytt@gmail.com> | 2016-05-11 14:32:50 -0700 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2016-05-13 23:00:56 -0700 |
commit | 40b42ae71779fb333259674b05f28de45219939d (patch) | |
tree | 0eed0a7dbcd29375d5d8b32f093e96fe5d36a10b /src | |
parent | a6d5eb507bbeac2055a224a15fd76e7f9425520b (diff) | |
download | scala-40b42ae71779fb333259674b05f28de45219939d.tar.gz scala-40b42ae71779fb333259674b05f28de45219939d.tar.bz2 scala-40b42ae71779fb333259674b05f28de45219939d.zip |
SI-8667 Caret at bad arg
Pick the first excessive positional arg for the caret.
Note that erroring on named args doesn't do the obvious thing
in this regard.
If `k` was removed from the signature, then `f(k=1, i=2, j=3)`
doesn't tell us much about the wrong arg, because naming takes
the `k=1` as an assignment, `i` as duplicate naming. No arg is
deemed extra, though further inspection of the conflicting args
might get there. Since assignment syntax in parens is more|less
deprecated (?), no more effort is done here.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 18 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 7 |
2 files changed, 16 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index e1055144f8..6b30d3834c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -538,7 +538,14 @@ trait ContextErrors { def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) = NormalTypeError(tree, "macro applications do not support named and/or default arguments") - def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree, expected: Int, supplied: Int, unknowns: List[Name]) = { + def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree, formals: List[Type], args: List[Tree], namelessArgs: List[Tree], argPos: Array[Int]) = { + val expected = formals.size + val supplied = args.size + // pick a caret. For f(k=1,i=2,j=3), argPos[0,-1,1] b/c `k=1` taken as arg0 + val excessive = { + val i = argPos.indexWhere(_ >= expected) + if (i < 0) tree else args(i min (supplied - 1)) + } val msg = { val badappl = { val excess = supplied - expected @@ -548,13 +555,16 @@ trait ContextErrors { else if (excess < 3 && expected <= 5) s"too many arguments ($supplied) for $target" else if (expected > 10) s"$supplied arguments but expected $expected for $target" else { - val oneOf = + val more = if (excess == 1) "one more argument" else if (excess > 0) s"$excess more arguments" else "too many arguments" - s"$oneOf than can be applied to $target" + s"$more than can be applied to $target" } } + val unknowns = (namelessArgs zip args) collect { + case (_: Assign, AssignOrNamedArg(Ident(name), _)) => name + } val suppl = unknowns.size match { case 0 => "" @@ -563,7 +573,7 @@ trait ContextErrors { } s"${badappl}${suppl}" } - NormalTypeError(tree, msg) + NormalTypeError(excessive, msg) } // can it still happen? see test case neg/overloaded-unapply.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 1d24d8c232..286de993db 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3331,11 +3331,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper duplErrorTree(WrongNumberOfArgsError(tree, fun)) } else if (lencmp > 0) { tryTupleApply orElse duplErrorTree { - val (namelessArgs, _) = removeNames(Typer.this)(args, params) - val wrongs = (namelessArgs zip args) collect { - case (_: Assign, AssignOrNamedArg(Ident(name), _)) => name - } - TooManyArgsNamesDefaultsError(tree, fun, expected = formals.size, supplied = args.size, wrongs) + val (namelessArgs, argPos) = removeNames(Typer.this)(args, params) + TooManyArgsNamesDefaultsError(tree, fun, formals, args, namelessArgs, argPos) } } else if (lencmp == 0) { // we don't need defaults. names were used, so this application is transformed |