summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaanm@gmail.com>2012-05-18 00:43:01 -0700
committerAdriaan Moors <adriaanm@gmail.com>2012-05-18 00:43:01 -0700
commitef7708812fac32ca0c2a05330222a6b0806c9054 (patch)
treee74d05a8438eef49246bf53deec775bc40b70659
parent446de86b3e51f45418cc87c0c9ec43c30bbab3d4 (diff)
parent3c79caa1369a7c1794097b669859118a71ab015e (diff)
downloadscala-ef7708812fac32ca0c2a05330222a6b0806c9054.tar.gz
scala-ef7708812fac32ca0c2a05330222a6b0806c9054.tar.bz2
scala-ef7708812fac32ca0c2a05330222a6b0806c9054.zip
Merge pull request #566 from lrytz/wip/t4928
Fix SI-4928
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala25
-rw-r--r--test/files/neg/names-defaults-neg.check12
-rw-r--r--test/files/neg/t4928.check5
-rw-r--r--test/files/neg/t4928.scala4
5 files changed, 36 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 0c1638b76f..df0258832c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -1040,8 +1040,12 @@ trait ContextErrors {
setError(arg)
}
- def DoubleParamNamesDefaultError(arg: Tree, name: Name)(implicit context: Context) = {
- issueNormalTypeError(arg, "parameter specified twice: "+ name)
+ def DoubleParamNamesDefaultError(arg: Tree, name: Name, pos: Int, otherName: Option[Name])(implicit context: Context) = {
+ val annex = otherName match {
+ case Some(oName) => "\nNote that that '"+ oName +"' is not a parameter name of the invoked method."
+ case None => ""
+ }
+ issueNormalTypeError(arg, "parameter '"+ name +"' is already specified at parameter position "+ pos + annex)
setError(arg)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 8ae254d35d..9e6b9617a5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -507,7 +507,7 @@ trait NamesDefaults { self: Analyzer =>
// maps indices from (order written by user) to (order of definition)
val argPos = Array.fill(args.length)(-1)
var positionalAllowed = true
- val namelessArgs = mapWithIndex(args) { (arg, index) =>
+ val namelessArgs = mapWithIndex(args) { (arg, argIndex) =>
arg match {
case arg @ AssignOrNamedArg(Ident(name), rhs) =>
def matchesName(param: Symbol) = !param.isSynthetic && (
@@ -519,30 +519,35 @@ trait NamesDefaults { self: Analyzer =>
case _ => false
})
)
- val pos = params indexWhere matchesName
- if (pos == -1) {
+ val paramPos = params indexWhere matchesName
+ if (paramPos == -1) {
if (positionalAllowed) {
- argPos(index) = index
+ argPos(argIndex) = argIndex
// prevent isNamed from being true when calling doTypedApply recursively,
// treat the arg as an assignment of type Unit
Assign(arg.lhs, rhs) setPos arg.pos
}
else UnknownParameterNameNamesDefaultError(arg, name)
}
- else if (argPos contains pos)
- DoubleParamNamesDefaultError(arg, name)
- else if (isAmbiguousAssignment(typer, params(pos), arg))
+ else if (argPos contains paramPos) {
+ val existingArgIndex = argPos.indexWhere(_ == paramPos)
+ val otherName = args(paramPos) match {
+ case AssignOrNamedArg(Ident(oName), rhs) if oName != name => Some(oName)
+ case _ => None
+ }
+ DoubleParamNamesDefaultError(arg, name, existingArgIndex+1, otherName)
+ } else if (isAmbiguousAssignment(typer, params(paramPos), arg))
AmbiguousReferenceInNamesDefaultError(arg, name)
else {
// if the named argument is on the original parameter
// position, positional after named is allowed.
- if (index != pos)
+ if (argIndex != paramPos)
positionalAllowed = false
- argPos(index) = pos
+ argPos(argIndex) = paramPos
rhs
}
case _ =>
- argPos(index) = index
+ argPos(argIndex) = argIndex
if (positionalAllowed) arg
else PositionalAfterNamedNamesDefaultError(arg)
}
diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check
index 01bbe2de4e..b5f544c97e 100644
--- a/test/files/neg/names-defaults-neg.check
+++ b/test/files/neg/names-defaults-neg.check
@@ -28,10 +28,10 @@ names-defaults-neg.scala:18: error: not found: value m
names-defaults-neg.scala:19: error: reference to x is ambiguous; it is both a method parameter and a variable in scope.
test8(x = 1)
^
-names-defaults-neg.scala:22: error: parameter specified twice: a
+names-defaults-neg.scala:22: error: parameter 'a' is already specified at parameter position 1
test1(1, a = 2)
^
-names-defaults-neg.scala:23: error: parameter specified twice: b
+names-defaults-neg.scala:23: error: parameter 'b' is already specified at parameter position 1
test1(b = 1, b = "2")
^
names-defaults-neg.scala:26: error: Int does not take parameters
@@ -61,10 +61,10 @@ and method g in object t7 of type (a: C, b: Int*)String
match argument types (C)
t7.g(new C()) // ambigous reference
^
-names-defaults-neg.scala:53: error: parameter specified twice: b
+names-defaults-neg.scala:53: error: parameter 'b' is already specified at parameter position 2
test5(a = 1, b = "dkjl", b = "dkj")
^
-names-defaults-neg.scala:54: error: parameter specified twice: b
+names-defaults-neg.scala:54: error: parameter 'b' is already specified at parameter position 2
test5(1, "2", b = 3)
^
names-defaults-neg.scala:55: error: when using named arguments, the vararg parameter has to be specified exactly once
@@ -110,7 +110,7 @@ names-defaults-neg.scala:91: error: deprecated parameter name a has to be distin
names-defaults-neg.scala:93: warning: the parameter name y has been deprecated. Use b instead.
deprNam3(y = 10, b = 2)
^
-names-defaults-neg.scala:93: error: parameter specified twice: b
+names-defaults-neg.scala:93: error: parameter 'b' is already specified at parameter position 1
deprNam3(y = 10, b = 2)
^
names-defaults-neg.scala:98: error: unknown parameter name: m
@@ -122,7 +122,7 @@ names-defaults-neg.scala:131: error: reference to var2 is ambiguous; it is both
names-defaults-neg.scala:134: error: missing parameter type for expanded function ((x$1) => a = x$1)
val taf2: Int => Unit = testAnnFun(a = _, b = get("+"))
^
-names-defaults-neg.scala:135: error: parameter specified twice: a
+names-defaults-neg.scala:135: error: parameter 'a' is already specified at parameter position 1
val taf3 = testAnnFun(b = _: String, a = get(8))
^
names-defaults-neg.scala:136: error: wrong number of parameters; expected = 2
diff --git a/test/files/neg/t4928.check b/test/files/neg/t4928.check
new file mode 100644
index 0000000000..06d4f22522
--- /dev/null
+++ b/test/files/neg/t4928.check
@@ -0,0 +1,5 @@
+t4928.scala:3: error: parameter 'a' is already specified at parameter position 1
+Note that that 'z' is not a parameter name of the invoked method.
+ f(z = 0, a = 1)
+ ^
+one error found
diff --git a/test/files/neg/t4928.scala b/test/files/neg/t4928.scala
new file mode 100644
index 0000000000..17a5980314
--- /dev/null
+++ b/test/files/neg/t4928.scala
@@ -0,0 +1,4 @@
+class C {
+ def f(a: Int, b: Int = 0) = 0
+ f(z = 0, a = 1)
+}