summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@epfl.ch>2009-06-20 08:19:40 +0000
committerLukas Rytz <lukas.rytz@epfl.ch>2009-06-20 08:19:40 +0000
commit0e170e4b695adafb3f3d5823026ccf8d10047be3 (patch)
tree58dd5a4ca9e73602222733720c5ead9612e0282e /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent60810d5c03ef614497d3a8ba5ad23d44e48194a8 (diff)
downloadscala-0e170e4b695adafb3f3d5823026ccf8d10047be3.tar.gz
scala-0e170e4b695adafb3f3d5823026ccf8d10047be3.tar.bz2
scala-0e170e4b695adafb3f3d5823026ccf8d10047be3.zip
improvements to names / defaults (implicits, ty...
improvements to names / defaults (implicits, type of defaults, #2064, ...)
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala71
1 files changed, 44 insertions, 27 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index e324e5793f..71e0af421f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -174,23 +174,32 @@ trait Typers { self: Analyzer =>
/** Find implicit arguments and pass them to given tree.
*/
- def applyImplicitArgs(tree: Tree): Tree = tree.tpe match {
+ def applyImplicitArgs(fun: Tree): Tree = fun.tpe match {
case MethodType(params, _) =>
- def implicitArg(pt: Type): SearchResult = {
- val result = inferImplicit(tree, pt, true, context)
- if (result == SearchFailure)
- context.error(tree.pos, "no implicit argument matching parameter type "+pt+" was found.")
- result
- }
+ def implicitArg(pt: Type): SearchResult =
+ inferImplicit(fun, pt, true, context)
+
+ var positional = true
val argResults = params map (_.tpe) map implicitArg
- val args = argResults map (_.tree)
+ val args = argResults.zip(params) flatMap {
+ case (arg, param) =>
+ if (arg != SearchFailure) {
+ if (positional) List(arg.tree)
+ else List(atPos(arg.tree.pos)(Assign(Ident(param.name), (arg.tree))))
+ } else {
+ if (!param.hasFlag(DEFAULTPARAM))
+ context.error(fun.pos, "could not find implicit value for parameter "+ param.name +":"+ param.tpe +".")
+ positional = false
+ Nil
+ }
+ }
for (s <- argResults map (_.subst)) {
- s traverse tree
+ s traverse fun
for (arg <- args) s traverse arg
}
- Apply(tree, args) setPos tree.pos
+ Apply(fun, args) setPos fun.pos
case ErrorType =>
- tree
+ fun
}
/** Infer an implicit conversion (``view'') between two types.
@@ -795,7 +804,7 @@ trait Typers { self: Analyzer =>
val tree1 = etaExpand(context.unit, tree)
//println("eta "+tree+" ---> "+tree1+":"+tree1.tpe)
typed(tree1, mode, pt)
- } else if (!meth.isConstructor && mt.paramTypes.isEmpty) { // (4.3)
+ } else if (!meth.isConstructor && mt.params.isEmpty) { // (4.3)
adapt(typed(Apply(tree, List()) setPos tree.pos), mode, pt)
} else if (context.implicitsEnabled) {
errorTree(tree, "missing arguments for "+meth+meth.locationString+
@@ -1990,6 +1999,9 @@ trait Typers { self: Analyzer =>
*/
def tryNamesDefaults: Tree = {
if (mt.isErroneous) setError(tree)
+ else if ((mode & PATTERNmode) != 0)
+ // #2064
+ errorTree(tree, "wrong number of arguments for "+ treeSymTypeMsg(fun))
else if (args.length > formals.length) {
tryTupleApply.getOrElse {
errorTree(tree, "too many arguments for "+treeSymTypeMsg(fun))
@@ -2020,22 +2032,27 @@ trait Typers { self: Analyzer =>
if (fun1.isErroneous) setError(tree)
else {
assert(isNamedApplyBlock(fun1), fun1)
- val NamedApplyInfo(qual, targs, previousArgss, _) =
- context.namedApplyBlockInfo.get._2
- val (allArgs, missing) = addDefaults(args, qual, targs, previousArgss, mt.params)
+ val NamedApplyInfo(qual, targs, previousArgss, _) = context.namedApplyBlockInfo.get._2
+ val blockIsEmpty = fun1 match {
+ case Block(Nil, _) =>
+ // if the block does not have any ValDef we can remove it. Note that the call to
+ // "transformNamedApplication" is always needed in order to obtain targs/previousArgss
+ context.namedApplyBlockInfo = None
+ true
+ case _ => false
+ }
+ val (allArgs, missing) = addDefaults(args, qual, targs, previousArgss, params, fun.pos)
if (allArgs.length == formals.length) {
- // a default for each missing argument was found
- val (namelessArgs, argPos) = removeNames(Typer.this)(allArgs, params)
- if (namelessArgs exists (_.isErroneous)) setError(tree)
- else
- transformNamedApplication(Typer.this, mode, pt)(
- treeCopy.Apply(tree, fun1, namelessArgs), argPos)
+ doTypedApply(tree, if (blockIsEmpty) fun else fun1, allArgs, mode, pt)
} else {
tryTupleApply.getOrElse {
val suffix =
if (missing.isEmpty) ""
- else ", unspecified parameter"+ (if (missing.length > 1) "s: " else ": ") +
- (missing.take(3).mkString(", ")) + (if (missing.length > 3) ", ..." else "")
+ else {
+ val missingStr = missing.take(3).map(_.name).mkString(", ") + (if (missing.length > 3) ", ..." else ".")
+ val sOpt = if (missing.length > 1) "s" else ""
+ ".\nUnspecified value parameter"+ sOpt +" "+ missingStr
+ }
errorTree(tree, "not enough arguments for "+treeSymTypeMsg(fun) + suffix)
}
}
@@ -2043,10 +2060,10 @@ trait Typers { self: Analyzer =>
}
}
- if (formals.length != args.length || // wrong nb of arguments
- args.exists(isNamed(_)) || // uses a named argument
- isNamedApplyBlock(fun)) { // fun was transformed to a named apply block =>
- // integrate this application into the block
+ if (formals.length != args.length || // wrong nb of arguments
+ args.exists(isNamed(_)) || // uses a named argument
+ isNamedApplyBlock(fun)) { // fun was transformed to a named apply block =>
+ // integrate this application into the block
tryNamesDefaults
} else {
val tparams = context.extractUndetparams()