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 | |
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.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 18 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 7 | ||||
-rw-r--r-- | test/files/neg/eta-expand-star.check | 2 | ||||
-rw-r--r-- | test/files/neg/macro-invalidusage-badargs.check | 2 | ||||
-rw-r--r-- | test/files/neg/multi-array.check | 2 | ||||
-rw-r--r-- | test/files/neg/protected-constructors.check | 7 | ||||
-rw-r--r-- | test/files/neg/t1112.check | 2 | ||||
-rw-r--r-- | test/files/neg/t1523.check | 2 | ||||
-rw-r--r-- | test/files/neg/t6920.check | 2 | ||||
-rw-r--r-- | test/files/neg/t7157.check | 24 | ||||
-rw-r--r-- | test/files/neg/t8006.check | 2 | ||||
-rw-r--r-- | test/files/neg/t8035-no-adapted-args.check | 2 | ||||
-rw-r--r-- | test/files/neg/t8667.check | 56 | ||||
-rw-r--r-- | test/files/neg/t8667.scala | 4 | ||||
-rw-r--r-- | test/files/neg/t876.check | 2 |
15 files changed, 79 insertions, 55 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 diff --git a/test/files/neg/eta-expand-star.check b/test/files/neg/eta-expand-star.check index f25e0a41ff..eba1721014 100644 --- a/test/files/neg/eta-expand-star.check +++ b/test/files/neg/eta-expand-star.check @@ -1,4 +1,4 @@ eta-expand-star.scala:6: error: too many arguments (2) for method apply: (v1: Seq[T])Unit in trait Function1 g(1, 2) - ^ + ^ one error found diff --git a/test/files/neg/macro-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check index 2f5f6d1064..ee549c45cb 100644 --- a/test/files/neg/macro-invalidusage-badargs.check +++ b/test/files/neg/macro-invalidusage-badargs.check @@ -15,5 +15,5 @@ Unspecified value parameter x. ^ Macros_Test_2.scala:9: error: too many arguments (2) for macro method foo: (x: Int)Int foo(4, 2) - ^ + ^ 5 errors found diff --git a/test/files/neg/multi-array.check b/test/files/neg/multi-array.check index a71f9b864a..06ffdc9fbc 100644 --- a/test/files/neg/multi-array.check +++ b/test/files/neg/multi-array.check @@ -1,4 +1,4 @@ multi-array.scala:7: error: too many arguments (2) for constructor Array: (_length: Int)Array[T] val a: Array[Int] = new Array(10, 10) - ^ + ^ one error found diff --git a/test/files/neg/protected-constructors.check b/test/files/neg/protected-constructors.check index 5c880cb672..0279f5815d 100644 --- a/test/files/neg/protected-constructors.check +++ b/test/files/neg/protected-constructors.check @@ -1,6 +1,6 @@ protected-constructors.scala:17: error: no arguments allowed for nullary constructor Foo1: ()dingus.Foo1 val foo1 = new Foo1("abc") - ^ + ^ protected-constructors.scala:18: error: constructor Foo2 in class Foo2 cannot be accessed in object P Access to protected constructor Foo2 not permitted because enclosing object P in package hungus is not a subclass of @@ -19,4 +19,7 @@ protected-constructors.scala:15: error: class Foo3 in object Ding cannot be acce object Ding in package dingus where target is defined class Bar3 extends Ding.Foo3("abc") ^ -four errors found +protected-constructors.scala:15: error: no arguments allowed for nullary constructor Object: ()Object + class Bar3 extends Ding.Foo3("abc") + ^ +5 errors found diff --git a/test/files/neg/t1112.check b/test/files/neg/t1112.check index 9c1254d176..e6058bf176 100644 --- a/test/files/neg/t1112.check +++ b/test/files/neg/t1112.check @@ -1,4 +1,4 @@ t1112.scala:12: error: too many arguments (2) for method call: (p: Int)(f: => Test.this.Type1)Unit call(0,() => System.out.println("here we are")) - ^ + ^ one error found diff --git a/test/files/neg/t1523.check b/test/files/neg/t1523.check index 656845a457..273d0f8cf7 100644 --- a/test/files/neg/t1523.check +++ b/test/files/neg/t1523.check @@ -1,4 +1,4 @@ t1523.scala:4: error: 25 more arguments than can be applied to method bug: (x: Any)Any def go() = bug("a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a", "a") - ^ + ^ one error found diff --git a/test/files/neg/t6920.check b/test/files/neg/t6920.check index 4e33aca3bc..d10abff03c 100644 --- a/test/files/neg/t6920.check +++ b/test/files/neg/t6920.check @@ -2,5 +2,5 @@ t6920.scala:9: error: too many arguments (2) for method applyDynamicNamed: (valu error after rewriting to CompilerError.this.test.applyDynamicNamed("crushTheCompiler")(scala.Tuple2("a", 1), scala.Tuple2("b", 2)) possible cause: maybe a wrong Dynamic method signature? test.crushTheCompiler(a = 1, b = 2) - ^ + ^ one error found diff --git a/test/files/neg/t7157.check b/test/files/neg/t7157.check index a043c5d403..0b81394946 100644 --- a/test/files/neg/t7157.check +++ b/test/files/neg/t7157.check @@ -1,22 +1,22 @@ Test_2.scala:5: error: no arguments allowed for nullary macro method m1_0_0: ()Unit m1_0_0(1) - ^ + ^ Test_2.scala:6: error: no arguments allowed for nullary macro method m1_0_0: ()Unit m1_0_0(1, 2) - ^ + ^ Test_2.scala:7: error: no arguments allowed for nullary macro method m1_0_0: ()Unit m1_0_0(1, 2, 3) - ^ + ^ Test_2.scala:9: error: not enough arguments for macro method m1_1_1: (x: Int)Unit. Unspecified value parameter x. m1_1_1() ^ Test_2.scala:11: error: too many arguments (2) for macro method m1_1_1: (x: Int)Unit m1_1_1(1, 2) - ^ + ^ Test_2.scala:12: error: too many arguments (3) for macro method m1_1_1: (x: Int)Unit m1_1_1(1, 2, 3) - ^ + ^ Test_2.scala:14: error: not enough arguments for macro method m1_2_2: (x: Int, y: Int)Unit. Unspecified value parameters x, y. m1_2_2() @@ -27,7 +27,7 @@ Unspecified value parameter y. ^ Test_2.scala:17: error: too many arguments (3) for macro method m1_2_2: (x: Int, y: Int)Unit m1_2_2(1, 2, 3) - ^ + ^ Test_2.scala:24: error: not enough arguments for macro method m1_1_inf: (x: Int, y: Int*)Unit. Unspecified value parameters x, y. m1_1_inf() @@ -42,23 +42,23 @@ Unspecified value parameters y, z. ^ Test_2.scala:35: error: no arguments allowed for nullary macro method m2_0_0: ()Unit m2_0_0()(1) - ^ + ^ Test_2.scala:36: error: no arguments allowed for nullary macro method m2_0_0: ()Unit m2_0_0()(1, 2) - ^ + ^ Test_2.scala:37: error: no arguments allowed for nullary macro method m2_0_0: ()Unit m2_0_0()(1, 2, 3) - ^ + ^ Test_2.scala:39: error: not enough arguments for macro method m2_1_1: (x: Int)Unit. Unspecified value parameter x. m2_1_1()() ^ Test_2.scala:41: error: too many arguments (2) for macro method m2_1_1: (x: Int)Unit m2_1_1()(1, 2) - ^ + ^ Test_2.scala:42: error: too many arguments (3) for macro method m2_1_1: (x: Int)Unit m2_1_1()(1, 2, 3) - ^ + ^ Test_2.scala:44: error: not enough arguments for macro method m2_2_2: (x: Int, y: Int)Unit. Unspecified value parameters x, y. m2_2_2()() @@ -69,7 +69,7 @@ Unspecified value parameter y. ^ Test_2.scala:47: error: too many arguments (3) for macro method m2_2_2: (x: Int, y: Int)Unit m2_2_2()(1, 2, 3) - ^ + ^ Test_2.scala:54: error: not enough arguments for macro method m2_1_inf: (x: Int, y: Int*)Unit. Unspecified value parameters x, y. m2_1_inf()() diff --git a/test/files/neg/t8006.check b/test/files/neg/t8006.check index 4e130670e4..6152d0fba3 100644 --- a/test/files/neg/t8006.check +++ b/test/files/neg/t8006.check @@ -2,5 +2,5 @@ t8006.scala:3: error: too many arguments (2) for method applyDynamicNamed: (valu error after rewriting to X.this.d.applyDynamicNamed("meth")(scala.Tuple2("value1", 10), scala.Tuple2("value2", 100)) possible cause: maybe a wrong Dynamic method signature? d.meth(value1 = 10, value2 = 100) // two arguments here, but only one is allowed - ^ + ^ one error found diff --git a/test/files/neg/t8035-no-adapted-args.check b/test/files/neg/t8035-no-adapted-args.check index 4b3cb39c76..0115dddc91 100644 --- a/test/files/neg/t8035-no-adapted-args.check +++ b/test/files/neg/t8035-no-adapted-args.check @@ -6,7 +6,7 @@ t8035-no-adapted-args.scala:4: warning: No automatic adaptation here: use explic ^ t8035-no-adapted-args.scala:4: error: too many arguments (3) for method f: (x: (Int, Int, Int))Int f(1, 2, 3) - ^ + ^ t8035-no-adapted-args.scala:5: warning: No automatic adaptation here: use explicit parentheses. signature: Test.f[T](x: T): Int given arguments: <none> diff --git a/test/files/neg/t8667.check b/test/files/neg/t8667.check index 4c3bcb78c8..82451ee5d6 100644 --- a/test/files/neg/t8667.check +++ b/test/files/neg/t8667.check @@ -1,7 +1,7 @@ t8667.scala:6: error: too many arguments (3) for constructor C: (a: Int, b: Int)C Note that 'c' is not a parameter name of the invoked method. def c2 = new C(a = 42, b = 17, c = 5) - ^ + ^ t8667.scala:7: error: unknown parameter name: c def c3 = new C(b = 42, a = 17, c = 5) ^ @@ -25,9 +25,13 @@ t8667.scala:10: error: too many arguments (3) for constructor C: (a: Int, b: Int Note that 'c' is not a parameter name of the invoked method. def c6 = new C(a = 42, c = 17, b = 5) ^ +t8667.scala:11: error: parameter 'a' is already specified at parameter position 1 +Note that 'c' is not a parameter name of the invoked method. + def c7 = new C(c = 42, a = 17, b = 5) + ^ t8667.scala:11: error: too many arguments (3) for constructor C: (a: Int, b: Int)C Note that 'c' is not a parameter name of the invoked method. - def c7 = new C(42, 17, c = 5) + def c7 = new C(c = 42, a = 17, b = 5) ^ t8667.scala:12: error: parameter 'b' is already specified at parameter position 2 def c8 = new C(42, 17, b = 5) @@ -42,38 +46,46 @@ Note that 'c' is not a parameter name of the invoked method. t8667.scala:13: error: too many arguments (4) for constructor C: (a: Int, b: Int)C Note that 'c', 'd' are not parameter names of the invoked method. def c9 = new C(a = 42, c = 17, d = 3, b = 5) - ^ + ^ t8667.scala:14: error: too many arguments (4) for constructor C: (a: Int, b: Int)C Note that 'd', 'c' are not parameter names of the invoked method. def c0 = new C(42, 17, d = 3, c = 5) - ^ -t8667.scala:24: error: no arguments allowed for nullary method f0: ()Int + ^ +t8667.scala:25: error: no arguments allowed for nullary method f0: ()Int f0(1) - ^ -t8667.scala:25: error: too many arguments (2) for method f1: (i: Int)Int + ^ +t8667.scala:26: error: too many arguments (2) for method f1: (i: Int)Int f1(1, 2) - ^ -t8667.scala:26: error: too many arguments (3) for method f1: (i: Int)Int + ^ +t8667.scala:27: error: too many arguments (3) for method f1: (i: Int)Int f1(1, 2, 3) - ^ -t8667.scala:27: error: 3 more arguments than can be applied to method f1: (i: Int)Int - f1(1, 2, 3, 4) - ^ + ^ t8667.scala:28: error: 3 more arguments than can be applied to method f1: (i: Int)Int + f1(1, 2, 3, 4) + ^ +t8667.scala:29: error: 3 more arguments than can be applied to method f1: (i: Int)Int Note that 'j' is not a parameter name of the invoked method. f1(1, j = 2, 3, 4) - ^ -t8667.scala:29: error: 3 more arguments than can be applied to method f1: (i: Int)Int + ^ +t8667.scala:30: error: 3 more arguments than can be applied to method f1: (i: Int)Int Note that 'j', 'k' are not parameter names of the invoked method. f1(1, j = 2, k = 3, 4) + ^ +t8667.scala:31: error: parameter 'i' is already specified at parameter position 1 +Note that 'k' is not a parameter name of the invoked method. + f2(k = 1, i = 2, j = 3) + ^ +t8667.scala:31: error: too many arguments (3) for method f2: (i: Int, j: Int)Int +Note that 'k' is not a parameter name of the invoked method. + f2(k = 1, i = 2, j = 3) ^ -t8667.scala:30: error: one more argument than can be applied to method f6: (i: Int, j: Int, k: Int, l: Int, m: Int, n: Int)Int +t8667.scala:32: error: one more argument than can be applied to method f6: (i: Int, j: Int, k: Int, l: Int, m: Int, n: Int)Int f6(1, 2, 3, 4, 5, 6, 7) - ^ -t8667.scala:31: error: 2 more arguments than can be applied to method f6: (i: Int, j: Int, k: Int, l: Int, m: Int, n: Int)Int + ^ +t8667.scala:33: error: 2 more arguments than can be applied to method f6: (i: Int, j: Int, k: Int, l: Int, m: Int, n: Int)Int f6(1, 2, 3, 4, 5, 6, 7, 8) - ^ -t8667.scala:32: error: 15 arguments but expected 12 for method f12: (i: Int, j: Int, k: Int, l: Int, m: Int, n: Int, o: Int, p: Int, q: Int, r: Int, s: Int, t: Int)Int + ^ +t8667.scala:34: error: 15 arguments but expected 12 for method f12: (i: Int, j: Int, k: Int, l: Int, m: Int, n: Int, o: Int, p: Int, q: Int, r: Int, s: Int, t: Int)Int f12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) - ^ -23 errors found + ^ +26 errors found diff --git a/test/files/neg/t8667.scala b/test/files/neg/t8667.scala index fe17eac84f..d55582ca6b 100644 --- a/test/files/neg/t8667.scala +++ b/test/files/neg/t8667.scala @@ -8,7 +8,7 @@ trait T { def c4 = new C(b = 42, a = 17, 5) def c5 = new C(a = 42, c = 17) def c6 = new C(a = 42, c = 17, b = 5) - def c7 = new C(42, 17, c = 5) + def c7 = new C(c = 42, a = 17, b = 5) def c8 = new C(42, 17, b = 5) def c9 = new C(a = 42, c = 17, d = 3, b = 5) def c0 = new C(42, 17, d = 3, c = 5) @@ -17,6 +17,7 @@ trait T { trait X { def f0() = 42 def f1(i: Int) = 42 + def f2(i: Int, j: Int) = 42 def f6(i: Int, j: Int, k: Int, l: Int, m: Int, n: Int) = 42 def f12(i: Int, j: Int, k: Int, l: Int, m: Int, n: Int, o: Int, p: Int, q: Int, r: Int, s: Int, t: Int) = 42 @@ -27,6 +28,7 @@ trait X { f1(1, 2, 3, 4) f1(1, j = 2, 3, 4) f1(1, j = 2, k = 3, 4) + f2(k = 1, i = 2, j = 3) f6(1, 2, 3, 4, 5, 6, 7) f6(1, 2, 3, 4, 5, 6, 7, 8) f12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) diff --git a/test/files/neg/t876.check b/test/files/neg/t876.check index 91dcbfd288..7df2e126a6 100644 --- a/test/files/neg/t876.check +++ b/test/files/neg/t876.check @@ -1,4 +1,4 @@ t876.scala:25: error: too many arguments (2) for method apply: (key: AssertionError.A)manager.B in class HashMap assert(manager.map(A2) == List(manager.map(A2, A1))) - ^ + ^ one error found |