aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2016-02-18 11:55:30 +0100
committerodersky <odersky@gmail.com>2016-02-18 11:55:30 +0100
commit4be70a5a8469c1355c84bef70936a81f899a9678 (patch)
tree488bea7c57cee865d122accbf4dd34d5fd4fd43a /src
parent3c85915ba7c98b253603fc873e6e41336a528bd6 (diff)
parent5c21583669ff9128784ce128d36e723b9d4517ee (diff)
downloaddotty-4be70a5a8469c1355c84bef70936a81f899a9678.tar.gz
dotty-4be70a5a8469c1355c84bef70936a81f899a9678.tar.bz2
dotty-4be70a5a8469c1355c84bef70936a81f899a9678.zip
Merge pull request #1073 from dotty-staging/fix-#576
Handle implicits with default parameters.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index b886d8663..854bc2094 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1437,10 +1437,15 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
wtp.paramTypes.foreach(instantiateSelected(_, tvarsToInstantiate))
val constr = ctx.typerState.constraint
def addImplicitArgs = {
- def implicitArgError(msg: => String): Tree = {
- ctx.error(msg, tree.pos.endPos)
+ val errors = new mutable.ListBuffer[() => String]
+ def implicitArgError(msg: => String) = {
+ errors += (() => msg)
EmptyTree
}
+ def issueErrors() = {
+ for (err <- errors) ctx.error(err(), tree.pos.endPos)
+ tree
+ }
val args = (wtp.paramNames, wtp.paramTypes).zipped map { (pname, formal) =>
def where = d"parameter $pname of $methodStr"
inferImplicit(formal, EmptyTree, tree.pos.endPos) match {
@@ -1452,12 +1457,27 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
implicitArgError(d"no implicit argument of type $formal found for $where" + failure.postscript)
}
}
- if (args.exists(_.isEmpty)) {
+ if (errors.nonEmpty) {
// If there are several arguments, some arguments might already
- // have influenced the context, binfing variables, but later ones
+ // have influenced the context, binding variables, but later ones
// might fail. In that case the constraint needs to be reset.
ctx.typerState.constraint = constr
- tree
+
+ // If method has default params, fall back to regular application
+ // where all inferred implicits are passed as named args.
+ if (tree.symbol.hasDefaultParams) {
+ val namedArgs = (wtp.paramNames, args).zipped.flatMap { (pname, arg) =>
+ arg match {
+ case EmptyTree => Nil
+ case _ => untpd.NamedArg(pname, untpd.TypedSplice(arg)) :: Nil
+ }
+ }
+ tryEither { implicit ctx =>
+ typed(untpd.Apply(untpd.TypedSplice(tree), namedArgs), pt)
+ } { (_, _) =>
+ issueErrors()
+ }
+ } else issueErrors()
}
else adapt(tpd.Apply(tree, args), pt)
}