Skip to content

Commit 40b42ae

Browse files
committed
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.
1 parent a6d5eb5 commit 40b42ae

15 files changed

+79
-55
lines changed

src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,14 @@ trait ContextErrors {
538538
def NamedAndDefaultArgumentsNotSupportedForMacros(tree: Tree, fun: Tree) =
539539
NormalTypeError(tree, "macro applications do not support named and/or default arguments")
540540

541-
def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree, expected: Int, supplied: Int, unknowns: List[Name]) = {
541+
def TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree, formals: List[Type], args: List[Tree], namelessArgs: List[Tree], argPos: Array[Int]) = {
542+
val expected = formals.size
543+
val supplied = args.size
544+
// pick a caret. For f(k=1,i=2,j=3), argPos[0,-1,1] b/c `k=1` taken as arg0
545+
val excessive = {
546+
val i = argPos.indexWhere(_ >= expected)
547+
if (i < 0) tree else args(i min (supplied - 1))
548+
}
542549
val msg = {
543550
val badappl = {
544551
val excess = supplied - expected
@@ -548,13 +555,16 @@ trait ContextErrors {
548555
else if (excess < 3 && expected <= 5) s"too many arguments ($supplied) for $target"
549556
else if (expected > 10) s"$supplied arguments but expected $expected for $target"
550557
else {
551-
val oneOf =
558+
val more =
552559
if (excess == 1) "one more argument"
553560
else if (excess > 0) s"$excess more arguments"
554561
else "too many arguments"
555-
s"$oneOf than can be applied to $target"
562+
s"$more than can be applied to $target"
556563
}
557564
}
565+
val unknowns = (namelessArgs zip args) collect {
566+
case (_: Assign, AssignOrNamedArg(Ident(name), _)) => name
567+
}
558568
val suppl =
559569
unknowns.size match {
560570
case 0 => ""
@@ -563,7 +573,7 @@ trait ContextErrors {
563573
}
564574
s"${badappl}${suppl}"
565575
}
566-
NormalTypeError(tree, msg)
576+
NormalTypeError(excessive, msg)
567577
}
568578

569579
// can it still happen? see test case neg/overloaded-unapply.scala

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3331,11 +3331,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
33313331
duplErrorTree(WrongNumberOfArgsError(tree, fun))
33323332
} else if (lencmp > 0) {
33333333
tryTupleApply orElse duplErrorTree {
3334-
val (namelessArgs, _) = removeNames(Typer.this)(args, params)
3335-
val wrongs = (namelessArgs zip args) collect {
3336-
case (_: Assign, AssignOrNamedArg(Ident(name), _)) => name
3337-
}
3338-
TooManyArgsNamesDefaultsError(tree, fun, expected = formals.size, supplied = args.size, wrongs)
3334+
val (namelessArgs, argPos) = removeNames(Typer.this)(args, params)
3335+
TooManyArgsNamesDefaultsError(tree, fun, formals, args, namelessArgs, argPos)
33393336
}
33403337
} else if (lencmp == 0) {
33413338
// we don't need defaults. names were used, so this application is transformed

test/files/neg/eta-expand-star.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
eta-expand-star.scala:6: error: too many arguments (2) for method apply: (v1: Seq[T])Unit in trait Function1
22
g(1, 2)
3-
^
3+
^
44
one error found

test/files/neg/macro-invalidusage-badargs.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ Unspecified value parameter x.
1515
^
1616
Macros_Test_2.scala:9: error: too many arguments (2) for macro method foo: (x: Int)Int
1717
foo(4, 2)
18-
^
18+
^
1919
5 errors found

test/files/neg/multi-array.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
multi-array.scala:7: error: too many arguments (2) for constructor Array: (_length: Int)Array[T]
22
val a: Array[Int] = new Array(10, 10)
3-
^
3+
^
44
one error found

test/files/neg/protected-constructors.check

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
protected-constructors.scala:17: error: no arguments allowed for nullary constructor Foo1: ()dingus.Foo1
22
val foo1 = new Foo1("abc")
3-
^
3+
^
44
protected-constructors.scala:18: error: constructor Foo2 in class Foo2 cannot be accessed in object P
55
Access to protected constructor Foo2 not permitted because
66
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
1919
object Ding in package dingus where target is defined
2020
class Bar3 extends Ding.Foo3("abc")
2121
^
22-
four errors found
22+
protected-constructors.scala:15: error: no arguments allowed for nullary constructor Object: ()Object
23+
class Bar3 extends Ding.Foo3("abc")
24+
^
25+
5 errors found

test/files/neg/t1112.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
t1112.scala:12: error: too many arguments (2) for method call: (p: Int)(f: => Test.this.Type1)Unit
22
call(0,() => System.out.println("here we are"))
3-
^
3+
^
44
one error found

test/files/neg/t1523.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
t1523.scala:4: error: 25 more arguments than can be applied to method bug: (x: Any)Any
22
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")
3-
^
3+
^
44
one error found

test/files/neg/t6920.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ t6920.scala:9: error: too many arguments (2) for method applyDynamicNamed: (valu
22
error after rewriting to CompilerError.this.test.applyDynamicNamed("crushTheCompiler")(scala.Tuple2("a", 1), scala.Tuple2("b", 2))
33
possible cause: maybe a wrong Dynamic method signature?
44
test.crushTheCompiler(a = 1, b = 2)
5-
^
5+
^
66
one error found

test/files/neg/t7157.check

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
Test_2.scala:5: error: no arguments allowed for nullary macro method m1_0_0: ()Unit
22
m1_0_0(1)
3-
^
3+
^
44
Test_2.scala:6: error: no arguments allowed for nullary macro method m1_0_0: ()Unit
55
m1_0_0(1, 2)
6-
^
6+
^
77
Test_2.scala:7: error: no arguments allowed for nullary macro method m1_0_0: ()Unit
88
m1_0_0(1, 2, 3)
9-
^
9+
^
1010
Test_2.scala:9: error: not enough arguments for macro method m1_1_1: (x: Int)Unit.
1111
Unspecified value parameter x.
1212
m1_1_1()
1313
^
1414
Test_2.scala:11: error: too many arguments (2) for macro method m1_1_1: (x: Int)Unit
1515
m1_1_1(1, 2)
16-
^
16+
^
1717
Test_2.scala:12: error: too many arguments (3) for macro method m1_1_1: (x: Int)Unit
1818
m1_1_1(1, 2, 3)
19-
^
19+
^
2020
Test_2.scala:14: error: not enough arguments for macro method m1_2_2: (x: Int, y: Int)Unit.
2121
Unspecified value parameters x, y.
2222
m1_2_2()
@@ -27,7 +27,7 @@ Unspecified value parameter y.
2727
^
2828
Test_2.scala:17: error: too many arguments (3) for macro method m1_2_2: (x: Int, y: Int)Unit
2929
m1_2_2(1, 2, 3)
30-
^
30+
^
3131
Test_2.scala:24: error: not enough arguments for macro method m1_1_inf: (x: Int, y: Int*)Unit.
3232
Unspecified value parameters x, y.
3333
m1_1_inf()
@@ -42,23 +42,23 @@ Unspecified value parameters y, z.
4242
^
4343
Test_2.scala:35: error: no arguments allowed for nullary macro method m2_0_0: ()Unit
4444
m2_0_0()(1)
45-
^
45+
^
4646
Test_2.scala:36: error: no arguments allowed for nullary macro method m2_0_0: ()Unit
4747
m2_0_0()(1, 2)
48-
^
48+
^
4949
Test_2.scala:37: error: no arguments allowed for nullary macro method m2_0_0: ()Unit
5050
m2_0_0()(1, 2, 3)
51-
^
51+
^
5252
Test_2.scala:39: error: not enough arguments for macro method m2_1_1: (x: Int)Unit.
5353
Unspecified value parameter x.
5454
m2_1_1()()
5555
^
5656
Test_2.scala:41: error: too many arguments (2) for macro method m2_1_1: (x: Int)Unit
5757
m2_1_1()(1, 2)
58-
^
58+
^
5959
Test_2.scala:42: error: too many arguments (3) for macro method m2_1_1: (x: Int)Unit
6060
m2_1_1()(1, 2, 3)
61-
^
61+
^
6262
Test_2.scala:44: error: not enough arguments for macro method m2_2_2: (x: Int, y: Int)Unit.
6363
Unspecified value parameters x, y.
6464
m2_2_2()()
@@ -69,7 +69,7 @@ Unspecified value parameter y.
6969
^
7070
Test_2.scala:47: error: too many arguments (3) for macro method m2_2_2: (x: Int, y: Int)Unit
7171
m2_2_2()(1, 2, 3)
72-
^
72+
^
7373
Test_2.scala:54: error: not enough arguments for macro method m2_1_inf: (x: Int, y: Int*)Unit.
7474
Unspecified value parameters x, y.
7575
m2_1_inf()()

test/files/neg/t8006.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ t8006.scala:3: error: too many arguments (2) for method applyDynamicNamed: (valu
22
error after rewriting to X.this.d.applyDynamicNamed("meth")(scala.Tuple2("value1", 10), scala.Tuple2("value2", 100))
33
possible cause: maybe a wrong Dynamic method signature?
44
d.meth(value1 = 10, value2 = 100) // two arguments here, but only one is allowed
5-
^
5+
^
66
one error found

test/files/neg/t8035-no-adapted-args.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ t8035-no-adapted-args.scala:4: warning: No automatic adaptation here: use explic
66
^
77
t8035-no-adapted-args.scala:4: error: too many arguments (3) for method f: (x: (Int, Int, Int))Int
88
f(1, 2, 3)
9-
^
9+
^
1010
t8035-no-adapted-args.scala:5: warning: No automatic adaptation here: use explicit parentheses.
1111
signature: Test.f[T](x: T): Int
1212
given arguments: <none>

test/files/neg/t8667.check

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
t8667.scala:6: error: too many arguments (3) for constructor C: (a: Int, b: Int)C
22
Note that 'c' is not a parameter name of the invoked method.
33
def c2 = new C(a = 42, b = 17, c = 5)
4-
^
4+
^
55
t8667.scala:7: error: unknown parameter name: c
66
def c3 = new C(b = 42, a = 17, c = 5)
77
^
@@ -25,9 +25,13 @@ t8667.scala:10: error: too many arguments (3) for constructor C: (a: Int, b: Int
2525
Note that 'c' is not a parameter name of the invoked method.
2626
def c6 = new C(a = 42, c = 17, b = 5)
2727
^
28+
t8667.scala:11: error: parameter 'a' is already specified at parameter position 1
29+
Note that 'c' is not a parameter name of the invoked method.
30+
def c7 = new C(c = 42, a = 17, b = 5)
31+
^
2832
t8667.scala:11: error: too many arguments (3) for constructor C: (a: Int, b: Int)C
2933
Note that 'c' is not a parameter name of the invoked method.
30-
def c7 = new C(42, 17, c = 5)
34+
def c7 = new C(c = 42, a = 17, b = 5)
3135
^
3236
t8667.scala:12: error: parameter 'b' is already specified at parameter position 2
3337
def c8 = new C(42, 17, b = 5)
@@ -42,38 +46,46 @@ Note that 'c' is not a parameter name of the invoked method.
4246
t8667.scala:13: error: too many arguments (4) for constructor C: (a: Int, b: Int)C
4347
Note that 'c', 'd' are not parameter names of the invoked method.
4448
def c9 = new C(a = 42, c = 17, d = 3, b = 5)
45-
^
49+
^
4650
t8667.scala:14: error: too many arguments (4) for constructor C: (a: Int, b: Int)C
4751
Note that 'd', 'c' are not parameter names of the invoked method.
4852
def c0 = new C(42, 17, d = 3, c = 5)
49-
^
50-
t8667.scala:24: error: no arguments allowed for nullary method f0: ()Int
53+
^
54+
t8667.scala:25: error: no arguments allowed for nullary method f0: ()Int
5155
f0(1)
52-
^
53-
t8667.scala:25: error: too many arguments (2) for method f1: (i: Int)Int
56+
^
57+
t8667.scala:26: error: too many arguments (2) for method f1: (i: Int)Int
5458
f1(1, 2)
55-
^
56-
t8667.scala:26: error: too many arguments (3) for method f1: (i: Int)Int
59+
^
60+
t8667.scala:27: error: too many arguments (3) for method f1: (i: Int)Int
5761
f1(1, 2, 3)
58-
^
59-
t8667.scala:27: error: 3 more arguments than can be applied to method f1: (i: Int)Int
60-
f1(1, 2, 3, 4)
61-
^
62+
^
6263
t8667.scala:28: error: 3 more arguments than can be applied to method f1: (i: Int)Int
64+
f1(1, 2, 3, 4)
65+
^
66+
t8667.scala:29: error: 3 more arguments than can be applied to method f1: (i: Int)Int
6367
Note that 'j' is not a parameter name of the invoked method.
6468
f1(1, j = 2, 3, 4)
65-
^
66-
t8667.scala:29: error: 3 more arguments than can be applied to method f1: (i: Int)Int
69+
^
70+
t8667.scala:30: error: 3 more arguments than can be applied to method f1: (i: Int)Int
6771
Note that 'j', 'k' are not parameter names of the invoked method.
6872
f1(1, j = 2, k = 3, 4)
73+
^
74+
t8667.scala:31: error: parameter 'i' is already specified at parameter position 1
75+
Note that 'k' is not a parameter name of the invoked method.
76+
f2(k = 1, i = 2, j = 3)
77+
^
78+
t8667.scala:31: error: too many arguments (3) for method f2: (i: Int, j: Int)Int
79+
Note that 'k' is not a parameter name of the invoked method.
80+
f2(k = 1, i = 2, j = 3)
6981
^
70-
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
82+
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
7183
f6(1, 2, 3, 4, 5, 6, 7)
72-
^
73-
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
84+
^
85+
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
7486
f6(1, 2, 3, 4, 5, 6, 7, 8)
75-
^
76-
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
87+
^
88+
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
7789
f12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
78-
^
79-
23 errors found
90+
^
91+
26 errors found

test/files/neg/t8667.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ trait T {
88
def c4 = new C(b = 42, a = 17, 5)
99
def c5 = new C(a = 42, c = 17)
1010
def c6 = new C(a = 42, c = 17, b = 5)
11-
def c7 = new C(42, 17, c = 5)
11+
def c7 = new C(c = 42, a = 17, b = 5)
1212
def c8 = new C(42, 17, b = 5)
1313
def c9 = new C(a = 42, c = 17, d = 3, b = 5)
1414
def c0 = new C(42, 17, d = 3, c = 5)
@@ -17,6 +17,7 @@ trait T {
1717
trait X {
1818
def f0() = 42
1919
def f1(i: Int) = 42
20+
def f2(i: Int, j: Int) = 42
2021
def f6(i: Int, j: Int, k: Int, l: Int, m: Int, n: Int) = 42
2122
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
2223

@@ -27,6 +28,7 @@ trait X {
2728
f1(1, 2, 3, 4)
2829
f1(1, j = 2, 3, 4)
2930
f1(1, j = 2, k = 3, 4)
31+
f2(k = 1, i = 2, j = 3)
3032
f6(1, 2, 3, 4, 5, 6, 7)
3133
f6(1, 2, 3, 4, 5, 6, 7, 8)
3234
f12(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)

test/files/neg/t876.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
t876.scala:25: error: too many arguments (2) for method apply: (key: AssertionError.A)manager.B in class HashMap
22
assert(manager.map(A2) == List(manager.map(A2, A1)))
3-
^
3+
^
44
one error found

0 commit comments

Comments
 (0)