diff options
author | Adriaan Moors <adriaanm@gmail.com> | 2012-05-18 00:43:01 -0700 |
---|---|---|
committer | Adriaan Moors <adriaanm@gmail.com> | 2012-05-18 00:43:01 -0700 |
commit | ef7708812fac32ca0c2a05330222a6b0806c9054 (patch) | |
tree | e74d05a8438eef49246bf53deec775bc40b70659 /src/compiler/scala | |
parent | 446de86b3e51f45418cc87c0c9ec43c30bbab3d4 (diff) | |
parent | 3c79caa1369a7c1794097b669859118a71ab015e (diff) | |
download | scala-ef7708812fac32ca0c2a05330222a6b0806c9054.tar.gz scala-ef7708812fac32ca0c2a05330222a6b0806c9054.tar.bz2 scala-ef7708812fac32ca0c2a05330222a6b0806c9054.zip |
Merge pull request #566 from lrytz/wip/t4928
Fix SI-4928
Diffstat (limited to 'src/compiler/scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 8 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 25 |
2 files changed, 21 insertions, 12 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) } |